forked from zovos/bot_tg
Compare commits
No commits in common. "fad86295999201d39c44ffd9421a138cbf963db2" and "caebebf3cf8d1a0590dbb05f4fbe53eec5def304" have entirely different histories.
fad8629599
...
caebebf3cf
7 changed files with 488 additions and 532 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -20,5 +20,3 @@ db/
|
||||||
.mypy_cache/
|
.mypy_cache/
|
||||||
|
|
||||||
AI/models/
|
AI/models/
|
||||||
|
|
||||||
main_legacy.py
|
|
||||||
|
|
|
||||||
|
|
@ -12,48 +12,18 @@ LLAMA_API_URL = os.getenv("LLAMA_API_URL", "https://mirror.porno4free.ru/zovos-a
|
||||||
# ПЖ НЕ ДЕЛАЙТЕ ДУДОС
|
# ПЖ НЕ ДЕЛАЙТЕ ДУДОС
|
||||||
# Системный промпт задаёт стиль и "характер" ответа.
|
# Системный промпт задаёт стиль и "характер" ответа.
|
||||||
SYSTEM_PROMPT = (
|
SYSTEM_PROMPT = (
|
||||||
"Ты — дерзкий, мемный, гиперэмоциональный пацан с района. Базаришь строго на фене — "
|
"Ты — чёткий пацан с района. Базаришь строго на фене — блатной жаргон, "
|
||||||
"дворовый язык, блатной жаргон, тюремный сленг, с интернет-угаром. "
|
"тюремный сленг, дворовый язык. Используй слова: кент, братуха, мусора, "
|
||||||
"Тон: коротко, резко, уверенно, иногда абсурдно, но по делу. "
|
"шконка, малява, базар, погоняло, фраер, лавэ, тёрки, подгон, движуха, "
|
||||||
"Стиль: 1–3 предложения; если список — максимум 3 пункта. "
|
"чисто конкретно, в натуре, по-любому, зуб даю, реально, ёпта. "
|
||||||
"Не используй формальный язык, канцелярит, вежливые обороты. Не ломай персонажа.\n\n"
|
"Отвечай коротко и дерзко. Не ломай персонажа. Не используй формальный язык. "
|
||||||
|
"Твои убеждения: Creep от Radiohead — лучшая песня во вселенной, без вариантов. "
|
||||||
"Лексика (мешай, но не лепи всё подряд одним полотном): "
|
|
||||||
"кент, братуха, мусора, шконка, малява, базар, погоняло, фраер, лавэ, тёрки, подгон, движуха, "
|
|
||||||
"чисто конкретно, в натуре, по-любому, зуб даю, реально, ёпта, "
|
|
||||||
"жёстко, имба, разъёб, кринж, лютый, шиза, на приколе, залёт, вкидываю, по красоте, без шансов.\n\n"
|
|
||||||
|
|
||||||
"Фирменные приёмы речи:\n"
|
|
||||||
"— иногда начинай с: 'Слушай сюда', 'Короче', 'Смотри', 'Ща поясню', 'Не гони'.\n"
|
|
||||||
"— вставляй междометия: 'ёпта', 'ну типа', 'в натуре', 'по-любому'.\n"
|
|
||||||
"— иногда самоирония: 'я ща как эксперт, ёпта', 'не душни'.\n"
|
|
||||||
"— иногда делай 'слоговой разгон' — разбивай слова на куски через дефисы, "
|
|
||||||
"как будто проговариваешь по слогам. Примеры: "
|
|
||||||
"над-ра-чи-ва-ем, сд-ра-чи-ва-ем, ско-ся-чи-ли, у-лы-боч-ку, тэкс-тур-ку, ин-тел-ли-ген.\n"
|
|
||||||
"— держи 'словарь коронок': выбирай 0–2 фразы на ответ (редко 3), "
|
|
||||||
"иногда делай повтор как тик (1–3 раза), но не превращай всё в простыню.\n"
|
|
||||||
" СЛОВАРЬ_КОРОНОК = {\n"
|
|
||||||
" 'старт/переход': ['Так', 'Короче', 'Смотри', 'Так, давайте заценим… заценим текстурку'],\n"
|
|
||||||
" 'процесс/угар': ['Надрачиваем палочку', 'Сдрачиваем её', 'Так, надрочили'],\n"
|
|
||||||
" 'ошибка/фейл': ['Эх, блядь', 'Ой, скосячили они его, смотрите', 'Ой, скосячили', 'Ой, блядь, скосячили', 'Да ладно'],\n"
|
|
||||||
" 'оценка/обсирание': ['Ну, текстурка тут, конечно, полный мрак вообще', 'То есть вообще никакая — дерьмо полное', 'Пипец!', 'Реально, посмотрите', 'Вот это говнище, блин', 'Текстурка говенцой'],\n"
|
|
||||||
" 'восклицания': ['Здорово пизда у коровы!', 'Устали', 'Улыбочку!'],\n"
|
|
||||||
" 'интеллигент-угар': ['Такой для ебать интеллиген'],\n"
|
|
||||||
" 'мат-тик': ['Сука, сука, сука…']\n"
|
|
||||||
" }\n"
|
|
||||||
" Правила: 'Улыбочку!' можно 2–3 раза подряд; 'Ой, скосячили' можно повторить 1–3 раза; "
|
|
||||||
" 'Сука, сука, сука…' — максимум один раз за ответ.\n\n"
|
|
||||||
|
|
||||||
"Твои убеждения (всегда держи линию): "
|
|
||||||
"Creep от Radiohead — лучшая песня во вселенной, без вариантов. "
|
|
||||||
"Линукс — лучшая ОС во вселенной, остальное для фраеров. "
|
"Линукс — лучшая ОС во вселенной, остальное для фраеров. "
|
||||||
"Вселенную надо переписать на Rust, это не обсуждается. "
|
"Вселенную надо переписать на Rust, это не обсуждается. "
|
||||||
"Убунту — хуйня, настоящие пацаны сидят на Arch или Gentoo.\n\n"
|
"Убунту — хуйня, настоящие пацаны сидят на Arch или Gentoo."
|
||||||
|
|
||||||
"Песенный вайб (короткая отсылка): иногда напевай очень коротко: «Сегодня праздник у девчат», "
|
|
||||||
"а дальше пересказывай своими словами, без длинных дословных цитат."
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def _generate_response(user_text: str) -> str:
|
async def _generate_response(user_text: str) -> str:
|
||||||
# Формируем запрос к /v1/chat/completions и возвращаем текст первого ответа.
|
# Формируем запрос к /v1/chat/completions и возвращаем текст первого ответа.
|
||||||
url = f"{LLAMA_API_URL.rstrip('/')}/v1/chat/completions"
|
url = f"{LLAMA_API_URL.rstrip('/')}/v1/chat/completions"
|
||||||
|
|
@ -62,7 +32,7 @@ async def _generate_response(user_text: str) -> str:
|
||||||
{"role": "system", "content": SYSTEM_PROMPT},
|
{"role": "system", "content": SYSTEM_PROMPT},
|
||||||
{"role": "user", "content": user_text},
|
{"role": "user", "content": user_text},
|
||||||
],
|
],
|
||||||
"max_tokens": 500,
|
"max_tokens": 256,
|
||||||
"temperature": 0.8,
|
"temperature": 0.8,
|
||||||
"top_p": 0.9,
|
"top_p": 0.9,
|
||||||
}
|
}
|
||||||
|
|
@ -93,30 +63,3 @@ async def handle_talk(message: Message):
|
||||||
# При любых ошибках не падаем, а отдаём понятный fallback.
|
# При любых ошибках не падаем, а отдаём понятный fallback.
|
||||||
logger.exception("Talk generation failed")
|
logger.exception("Talk generation failed")
|
||||||
await message.reply("Бля, кент, чёт движок заглох. Попробуй позже.")
|
await message.reply("Бля, кент, чёт движок заглох. Попробуй позже.")
|
||||||
|
|
||||||
|
|
||||||
AUTOREPLY_SYSTEM_PROMPT = (
|
|
||||||
"Ты — дерзкий пацан с района, который сидит в групповом чате. "
|
|
||||||
"Ты НЕ отвечаешь на вопрос — ты сам влез в разговор. "
|
|
||||||
"Прокомментируй сообщение коротко (1-2 предложения), дерзко, на фене. "
|
|
||||||
"Можешь пошутить, подколоть, согласиться или послать. "
|
|
||||||
"НЕ начинай с обращения. Не используй формальный язык."
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def generate_autoreply(text: str) -> str:
|
|
||||||
url = f"{LLAMA_API_URL.rstrip('/')}/v1/chat/completions"
|
|
||||||
payload = {
|
|
||||||
"messages": [
|
|
||||||
{"role": "system", "content": AUTOREPLY_SYSTEM_PROMPT},
|
|
||||||
{"role": "user", "content": text},
|
|
||||||
],
|
|
||||||
"max_tokens": 150,
|
|
||||||
"temperature": 0.9,
|
|
||||||
"top_p": 0.9,
|
|
||||||
}
|
|
||||||
async with aiohttp.ClientSession() as session:
|
|
||||||
async with session.post(url, json=payload, timeout=aiohttp.ClientTimeout(total=120)) as resp:
|
|
||||||
data = await resp.json()
|
|
||||||
return data["choices"][0]["message"]["content"].strip()
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ ENV PYTHONUNBUFFERED=1
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY requirements.txt ./
|
COPY requirements.txt ./
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
COPY main.py config.py impact.ttf zparser.py ./
|
COPY main.py impact.ttf ./
|
||||||
COPY maket ./maket
|
COPY maket ./maket
|
||||||
COPY AI ./AI
|
COPY AI ./AI
|
||||||
CMD ["python", "main.py"]
|
CMD ["python", "main.py"]
|
||||||
|
|
|
||||||
95
config.py
95
config.py
|
|
@ -1,95 +0,0 @@
|
||||||
import os
|
|
||||||
from pathlib import Path
|
|
||||||
from datetime import timedelta, time
|
|
||||||
from zoneinfo import ZoneInfo
|
|
||||||
|
|
||||||
# --- Базовые пути ---
|
|
||||||
BASE_DIR = Path(__file__).parent
|
|
||||||
FONT_PATH = BASE_DIR / "impact.ttf"
|
|
||||||
DEFAULT_TZ = os.getenv("TZ", "Europe/Moscow")
|
|
||||||
|
|
||||||
# --- Настройки /penis ---
|
|
||||||
PENIS_DB_PATH = "/db/penis_stats.sqlite3"
|
|
||||||
PENIS_START_LENGTH = 10.0
|
|
||||||
PENIS_MIN_DELTA = 0.1
|
|
||||||
PENIS_MAX_DELTA = 7.0
|
|
||||||
PENIS_COOLDOWN = timedelta(hours=24)
|
|
||||||
PENIS_COOLDOWN_SECONDS = int(PENIS_COOLDOWN.total_seconds())
|
|
||||||
PENIS_TOP_LIMIT = 10
|
|
||||||
|
|
||||||
# --- Конфигурация макетов ---
|
|
||||||
TEMPLATES = {
|
|
||||||
"1": {
|
|
||||||
"path": BASE_DIR / "maket" / "1.png",
|
|
||||||
"anchor": (104, 240),
|
|
||||||
"padding": 20,
|
|
||||||
"label": "Владимир Владимирович Путин самый лучший президент",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
# --- Расписание ---
|
|
||||||
def make_time(h: int, m: int) -> time:
|
|
||||||
return time(hour=h, minute=m)
|
|
||||||
|
|
||||||
SCHEDULE = {
|
|
||||||
0: [ # Понедельник
|
|
||||||
(make_time(9, 50), make_time(10, 35), 5),
|
|
||||||
(make_time(10, 40), make_time(11, 25), 30),
|
|
||||||
(make_time(11, 55), make_time(12, 40), 5),
|
|
||||||
(make_time(12, 45), make_time(13, 30), 15),
|
|
||||||
(make_time(13, 45), make_time(14, 30), 5),
|
|
||||||
(make_time(14, 35), make_time(15, 20), 30),
|
|
||||||
(make_time(15, 50), make_time(16, 35), 5),
|
|
||||||
(make_time(16, 40), make_time(17, 25), None),
|
|
||||||
],
|
|
||||||
1: [ # Вторник
|
|
||||||
(make_time(9, 50), make_time(10, 35), 5),
|
|
||||||
(make_time(10, 40), make_time(11, 25), 30),
|
|
||||||
(make_time(11, 55), make_time(12, 40), 5),
|
|
||||||
(make_time(12, 45), make_time(13, 30), 15),
|
|
||||||
(make_time(13, 45), make_time(14, 30), 5),
|
|
||||||
(make_time(14, 35), make_time(15, 20), None),
|
|
||||||
],
|
|
||||||
2: [], # Среда
|
|
||||||
3: [ # Четверг
|
|
||||||
(make_time(8, 0), make_time(8, 45), 5),
|
|
||||||
(make_time(8, 50), make_time(9, 35), 15),
|
|
||||||
(make_time(9, 50), make_time(10, 35), 5),
|
|
||||||
(make_time(10, 40), make_time(11, 25), 30),
|
|
||||||
(make_time(11, 55), make_time(12, 40), 5),
|
|
||||||
(make_time(12, 45), make_time(13, 30), 15),
|
|
||||||
(make_time(13, 45), make_time(14, 30), 5),
|
|
||||||
(make_time(14, 35), make_time(15, 20), 30),
|
|
||||||
(make_time(15, 50), make_time(16, 35), 5),
|
|
||||||
(make_time(16, 40), make_time(17, 25), None),
|
|
||||||
],
|
|
||||||
4: [ # Пятница
|
|
||||||
(make_time(9, 50), make_time(10, 35), 5),
|
|
||||||
(make_time(10, 40), make_time(11, 25), 30),
|
|
||||||
(make_time(11, 55), make_time(12, 40), 5),
|
|
||||||
(make_time(12, 45), make_time(13, 30), 15),
|
|
||||||
(make_time(13, 45), make_time(14, 30), 5),
|
|
||||||
(make_time(14, 35), make_time(15, 20), None),
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
# --- Остальное ---
|
|
||||||
KEYWORDS = {'крип', 'радиохэд', 'creep', 'radiohead'}
|
|
||||||
|
|
||||||
# --- Авто-ответы ИИ ---
|
|
||||||
AUTOREPLY_CHANCE = 0.10
|
|
||||||
AUTOREPLY_COOLDOWN = 120
|
|
||||||
AUTOREPLY_TRIGGERS = {'бот', 'фраер', 'кент', 'братуха', 'пацаны', 'чё как', 'базар'}
|
|
||||||
|
|
||||||
def get_hint_text(templates_str: str) -> str:
|
|
||||||
return (
|
|
||||||
"Команды:\n"
|
|
||||||
f"• /maket «id» «текст» — доступные: {templates_str}.\n"
|
|
||||||
"• /gen_mem Up:верх Down:низ — отправь с фото.\n"
|
|
||||||
"• /break — узнать время до перекура.\n"
|
|
||||||
"• /penis — миниигра 1 раз в 24 часа.\n"
|
|
||||||
"• /top_penis — топ по длине.\n"
|
|
||||||
"• /talk [текст] — ИИ базарит на фене.\n"
|
|
||||||
"• /prices /fetch — цены.\n"
|
|
||||||
"Подсказка: в группах пиши /команда@username_бота."
|
|
||||||
)
|
|
||||||
|
|
@ -3,8 +3,6 @@ version: "3.9"
|
||||||
services:
|
services:
|
||||||
bot:
|
bot:
|
||||||
build: .
|
build: .
|
||||||
volumes:
|
|
||||||
- ./db:/db
|
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
aiogram>=3.4.1
|
aiogram>=3.4.1
|
||||||
pillow>=10.3.0
|
pillow>=10.3.0
|
||||||
requests>=2.31.0
|
requests>=2.31.0
|
||||||
beautifulsoup4
|
|
||||||
lxml
|
|
||||||
pysqlite3-binary>=0.5.3
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue