фикс я хуй знает много чего я добавил

This commit is contained in:
huker667 committed 2026-08-07 23:03:12 +03:00
1 parent ca0f5bf3de
commit 891131b88e
11 files changed
+845 -572

No files matched your search

+31 -10
View File
@@ -1,12 +1,33 @@
Copyright 2025 Den Open Plov License Version 1 (OPLv1)
Permission to use, copy, modify, and/or distribute this software for any Permission is granted for free use, copying, modification, and
purpose with or without fee is hereby granted. distribution of this software for non-commercial purposes,
provided that this license notice is retained.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH Any derivative works and modifications must be distributed under
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND this same license with open source code.
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM Closing the source code or distribution under a proprietary
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR license is prohibited.
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. Distribution of compiled (binary) versions of this software
without publicly available source code from which the software was
built is prohibited.
Code under this license may only be combined with code under
licenses that require maintaining open source code.
Combining with code under licenses that permit closing source code
or unrestricted commercial use is prohibited.
When combining with code under other copyleft licenses, the
resulting work must comply with the requirements of both licenses.
Project dependencies are not subject to the requirements of this
license and may be used according to their own terms. This license
applies only to the original project code and its derivative
works.
The software is provided "as is", without any warranties. The
copyright holder is not liable for any damages arising from the
use of the software.
+104
View File
@@ -0,0 +1,104 @@
import aiohttp
import asyncio
import json
import gconfig
try:
from config import *
except:
gconfig.copy_config()
finally:
from config import *
async def make_request(url, headers, payload):
async with aiohttp.ClientSession(headers=headers) as session:
async with session.post(url, json=payload) as response:
if payload.get("stream") == True:
async for line in response.content:
line = line.decode("utf-8").strip()
if line.startswith("data:"):
data = line[5:].strip()
if data == "DONE":
break
else:
# data = await response.text()
yield data
else:
response_data = b""
async for chunk in response.content.iter_chunks():
response_data += chunk[0]
yield response_data.decode()
async def completions(
url,
api_key,
model,
messages,
stream=False,
max_tokens=MAX_TOKENS,
extra=None
):
print(url)
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
payload = {
"messages": messages,
"model": model,
"stream": stream,
"max_tokens": max_tokens,
}
if extra:
payload = payload | extra
if stream:
async for data in make_request(url+"/chat/completions", headers, payload):
try:
yield json.loads(data)
except:
yield data
else:
async for data in make_request(url+"/chat/completions", headers, payload):
try:
yield json.loads(data)
except:
yield data
async def responses(
url,
api_key,
model,
input,
stream=False,
max_tokens=MAX_TOKENS,
extra=None
):
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
payload = {
"model": model,
"input": input,
"stream": stream,
"max_tokens": max_tokens,
}
if extra:
payload = payload | extra
if stream:
async for data in make_request(url+"/chat/completions", headers, payload):
try:
yield json.loads(data)
except:
yield data
else:
async for data in make_request(url+"/chat/completions", headers, payload):
try:
yield json.loads(data)
except:
yield data
+10 -98
View File
@@ -860,114 +860,26 @@ async def settings_callback(callback: CallbackQuery):
await settings_handler(callback) await settings_handler(callback)
@router.callback_query(F.data.startswith("set_stream%")) @router.callback_query(F.data.startswith("set%"))
async def set_stream_callback(callback: CallbackQuery): async def set_setting_callback(callback: CallbackQuery):
current_user_id = str(callback.from_user.id) current_user_id = str(callback.from_user.id)
data = callback.data.split("%", 2) data = callback.data.split("%", 3)
user_id = data[1] user_id = data[2]
if user_id != current_user_id: if user_id != current_user_id:
await callback.answer("нет, не трогай это не твое") await callback.answer("нет, не трогай это не твое")
return return
new_status = callback.data.split("%")[2] new_status = callback.data.split("%")[3]
config = get_user_config(user_id) config = get_user_config(user_id)
if new_status == "native" or new_status == "edit":
set_user_config(
user_id,
config.get("model"),
new_status,
config.get("call"),
config.get("prompt"),
config.get("notify"),
config.get("markdown"),
config.get("prompts"),
)
else:
set_user_config(
user_id,
config.get("model"),
"none",
config.get("call"),
config.get("prompt"),
config.get("notify"),
config.get("markdown"),
config.get("prompts"),
)
await settings_handler(callback)
alo = {
data[1]: new_status
}
@router.callback_query(F.data.startswith("set_call%")) set_user_setting(
async def set_call_callback(callback: CallbackQuery):
current_user_id = str(callback.from_user.id)
data = callback.data.split("%", 2)
user_id = data[1]
if user_id != current_user_id:
await callback.answer("нет, не трогай это не твое")
return
new_status = callback.data.split("%")[2]
config = get_user_config(user_id)
set_user_config(
user_id, user_id,
config.get("model"), **alo
config.get("stream"),
new_status,
config.get("prompt"),
config.get("notify"),
config.get("markdown"),
config.get("prompts")
)
await settings_handler(callback)
@router.callback_query(F.data.startswith("set_notify%"))
async def set_notify_callback(callback: CallbackQuery):
current_user_id = str(callback.from_user.id)
data = callback.data.split("%", 2)
user_id = data[1]
if user_id != current_user_id:
await callback.answer("нет, не трогай это не твое")
return
new_status = callback.data.split("%")[2]
config = get_user_config(user_id)
set_user_config(
user_id,
config.get("model"),
config.get("stream"),
config.get("call"),
config.get("prompt"),
new_status,
config.get("markdown"),
config.get("prompts")
)
await settings_handler(callback)
@router.callback_query(F.data.startswith("set_markdown%"))
async def set_markdown_callback(callback: CallbackQuery):
current_user_id = str(callback.from_user.id)
data = callback.data.split("%", 2)
user_id = data[1]
if user_id != current_user_id:
await callback.answer("нет, не трогай это не твое")
return
new_status = data[2]
config = get_user_config(user_id)
set_user_config(
user_id,
config.get("model"),
config.get("stream"),
config.get("call"),
config.get("prompt"),
config.get("notify"),
new_status,
config.get("prompts")
) )
await settings_handler(callback) await settings_handler(callback)
+10 -8
View File
@@ -27,6 +27,8 @@ from collections import Counter
from colors import * from colors import *
from config import * from config import *
from statistics import * from statistics import *
from vars import *
from helpers import *
from supergenerator import * from supergenerator import *
router = Router() router = Router()
@@ -69,7 +71,7 @@ async def stats_handler(message: Message):
top_models = models.most_common(5) top_models = models.most_common(5)
top_streams = streams.most_common(2) top_streams = streams.most_common(2)
top_prompts = prompts.most_common(5) top_prompts = prompts.most_common(10)
text = [ text = [
"✅ *общая статистика*", "✅ *общая статистика*",
@@ -85,8 +87,8 @@ async def stats_handler(message: Message):
*(f"- `{s}`: {c}" for s, c in top_streams), *(f"- `{s}`: {c}" for s, c in top_streams),
"👀топ режимов вызова:", "👀топ режимов вызова:",
*(f"- `{c}`: {n}" for c, n in calls.most_common()), *(f"- `{c}`: {n}" for c, n in calls.most_common()),
"📝топ 5 промптов:", "📝топ 10 промптов:",
*(f"- `{c}`: {n}" for c, n in prompts.most_common()), *(f"- `{c}`: {n}" for c, n in top_prompts.most_common()),
] ]
await message.reply("\n".join(text)) await message.reply("\n".join(text))
@@ -389,7 +391,7 @@ async def prompt_handler(message: Message):
config = get_user_config(user_id) config = get_user_config(user_id)
system_prompt_name = config["prompt"] system_prompt_name = config["prompt"]
if system_prompt_name in SYSTEM_PROMPTS: if system_prompt_name in SYSTEM_PROMPTS:
system_prompt = SYSTEM_PROMPTS[system_prompt_name] system_prompt = SYSTEM_PROMPTS[system_prompt_name]["text"]
else: else:
await message.reply( await message.reply(
f"🤝 произошла ошибка при отображении промпта `{system_prompt_name}`\n*для фото*: ```prompt\n{IMAGE_PROMPT}```изменить системный промпт узбекгпт пока что нельзя." f"🤝 произошла ошибка при отображении промпта `{system_prompt_name}`\n*для фото*: ```prompt\n{IMAGE_PROMPT}```изменить системный промпт узбекгпт пока что нельзя."
@@ -480,21 +482,21 @@ async def settings_handler(event: Union[Message, CallbackQuery]):
[ [
InlineKeyboardButton( InlineKeyboardButton(
text=f"стрим: {stream_status}", text=f"стрим: {stream_status}",
callback_data=f"set_stream%{user_id}%{stream_cb}", callback_data=f"set%stream%{user_id}%{stream_cb}",
), ),
InlineKeyboardButton( InlineKeyboardButton(
text=f"отклик: {call_status}", text=f"отклик: {call_status}",
callback_data=f"set_call%{user_id}%{call_cb}", callback_data=f"set%call%{user_id}%{call_cb}",
) )
], ],
[ [
InlineKeyboardButton( InlineKeyboardButton(
text=f"рассылка: {notify_status}", text=f"рассылка: {notify_status}",
callback_data=f"set_notify%{user_id}%{notify_cb}", callback_data=f"set%notify%{user_id}%{notify_cb}",
), ),
InlineKeyboardButton( InlineKeyboardButton(
text=f"маркдаун: {markdown_status}", text=f"маркдаун: {markdown_status}",
callback_data=f"set_markdown%{user_id}%{markdown_cb}", callback_data=f"set%markdown%{user_id}%{markdown_cb}",
), ),
], ],
+35 -9
View File
@@ -4,39 +4,57 @@ from dotenv import load_dotenv
load_dotenv() load_dotenv()
ADMIN_ID = 8243488179 # айди аккаунта админа для команд /reset /broadcast /clean и так далее
ADMIN_ID = 8935141038
# поставь "" пустой da если хочешь отключить поддержку голосовых # поставь "" пустой da если хочешь отключить поддержку голосовых
VOSK_API = "http://127.0.0.1:8080/stt" VOSK_API = "http://127.0.0.1:8080/stt"
# сколько сообщений хранить в контексте
MAX_CONTEXT = 7 MAX_CONTEXT = 7
MAX_PROMPT = 4000 # максимальное количество символов в промпте +файлы
MAX_TOKENS = 9000 MAX_PROMPT = 16000
# макс токены генерация
MAX_TOKENS = 4000
# макс символы (только в режиме стрима работает мне лень фиксить)
MAX_SYMBOLS = 13400
# макс количество кастомных промптов
MAX_PROMPTS = 8 MAX_PROMPTS = 8
# каждые n (400) символов обновлять стриминг поток
STREAMING_SPLIT_SYMBOLS = 400
# не важно
BEN_IDS = [-1002147940521, -1001834656942, -1003142512395] BEN_IDS = [-1002147940521, -1001834656942, -1003142512395]
ABEN_IDS = [-1002147940521, -1001834656942, -1003142512395] ABEN_IDS = [-1002147940521, -1001834656942, -1003142512395]
REPORN_IDS = [-1002147940521, -1002775610996, -1001834656942, -1003142512395] REPORN_IDS = [-1002147940521, -1002775610996, -1001834656942, -1003142512395]
# юз бота без @
BOT_USERNAME = "UzbekGPTTestBot" BOT_USERNAME = "UzbekGPTTestBot"
# на что бот откликается
BOT_CALLS = ["узбек", "uzbek", f"@{BOT_USERNAME}"] BOT_CALLS = ["узбек", "uzbek", f"@{BOT_USERNAME}"]
# дефолт настройки для новых юзеров
DEFAULT_MODEL = "ollama*gemma4:31b-cloud" DEFAULT_MODEL = "ollama*gemma4:31b-cloud"
IMAGE_MODEL = "ollama*gemma3:27b-cloud"
DEFAULT_STREAM = "none" DEFAULT_STREAM = "none"
DEFAULT_CALL = "da" DEFAULT_CALL = "da"
DEFAULT_PROMPT = "standart" DEFAULT_PROMPT = "standart"
DEFAULT_NOTIFY = "da" DEFAULT_NOTIFY = "da"
# поставь DEFAULT_MARKDOWN на "" если хочешь спросить пользователя что он хочет при первом соо da.
DEFAULT_MARKDOWN = "old" DEFAULT_MARKDOWN = "old"
# модель которая умеет принимать картинки очень важно
IMAGE_MODEL = "ollama*gemma3:27b-cloud"
# я забыл если честно
SHOW_ACC_MSG = True SHOW_ACC_MSG = True
# можно отключить некоторые команды
SETTINGS_COMMAND = True SETTINGS_COMMAND = True
CLEAR_COMMAND = True CLEAR_COMMAND = True
PROMPT_COMMAND = True PROMPT_COMMAND = True
CONFIG_COMMAND = True CONFIG_COMMAND = True
# /settings -> о боте
ABOUT_BOT = ( ABOUT_BOT = (
"✅ *об узбекгпт* ✅\n" "✅ *об узбекгпт* ✅\n"
"- создал @zsh69 (хукер667)\n" "- создал @zsh69 (хукер667)\n"
@@ -45,8 +63,10 @@ ABOUT_BOT = (
"- подпешис: t.me/hukerass" "- подпешис: t.me/hukerass"
) )
DONATE_LINK = "" # /settings -> донат, на самом деле можно вставить любой текст а не ссылку
DONATE_LINK = "https://t.me/send?start=IVRLB58MrhCp"
# провайдеры ваши хз
PROVIDERS = { PROVIDERS = {
"ollama": { "ollama": {
"name": "оллама", "name": "оллама",
@@ -68,14 +88,20 @@ PROVIDERS = {
# }, # },
} }
# какие модели есть и настройки (все настройки ищи в коде)
# - например тут vision ты указываешь умеет ли эта модель смотреть фото.
# если нет, то модель в IMAGE_MODEL будет генерить анализ по фото для
# твоей модели.
# если да, то модель будет напрямую смотреть фото в messages
MODELS = { MODELS = {
"ollama": { "ollama": {
"gemma3:27b-cloud": {"n_tok": 7, "e_tok": 15, "vision": True}, "gemma3:27b-cloud": {"vision": False},
"gemma4:31b-cloud": {"n_tok": 30, "e_tok": 50, "vision": True}, "gemma4:31b-cloud": {"vision": True},
}, },
"krutoiapi": { "krutoiapi": {
"da": {"n_tok": 30, "e_tok": 50, "vision": False}, "claude-mythos-5": {"vision": False},
}, },
} }
# АХУЕТЬ ТОКЕН!!
API_TOKEN = os.getenv("API_TOKEN") API_TOKEN = os.getenv("API_TOKEN")
+292 -1
View File
@@ -1,11 +1,14 @@
import re
import time import time
import shelve
import requests import requests
from aiogram.methods import AnswerGuestQuery, SendPoll from aiogram.methods import AnswerGuestQuery, SendPoll
from aiogram.types import InlineQueryResultArticle, InputTextMessageContent, InputRichMessageContent, InputRichMessage, Message from aiogram.types import InlineQueryResultArticle, InputTextMessageContent, InputRichMessageContent, InputRichMessage, Message
from aiogram.enums import ChatType from aiogram.enums import ChatType
from supergenerator import * from vars import *
from config import *
def is_blocked(user_id): def is_blocked(user_id):
@@ -162,3 +165,291 @@ async def mans(message, text):
else: else:
return await message.reply(text) return await message.reply(text)
def graph_emoji(status):
match status:
case "done":
return "✅"
case "error":
return "🚫"
case "make":
return "💭"
case "wait":
return "⏳"
case _:
return "🥺"
def make_graph(message, process):
text = ""
replied = message.reply_to_message or None
user_id = message.from_user.id
config = get_user_config(user_id)
im_model = IMAGE_MODEL.split("*", 1)
model = config["model"].split("*", 1)
photo_a = process.get("photo_a", None)
photo = process.get("photo", None)
stt = process.get("stt", None)
t = process.get("text", None)
if photo_a:
text += f"{graph_emoji(photo_a)} анализ фото (в ответе)\n"
if photo:
text += f"{graph_emoji(photo)} анализ фото\n"
if stt:
text += f"{graph_emoji(stt)} stt (голос -> текст)\n"
text += f"{graph_emoji(t)} запрос `{model[1]}` (`{model[0]}`)\n"
if replied and replied.document:
text += f"↳ {replied.document.file_size} файл (в ответе)\n"
if message.document:
text += f"↳ {message.document.file_size} файл\n"
if replied and replied.photo:
text += "↳ фото (в ответе)\n"
if message.photo:
text += "↳ фото\n"
if replied and replied.location:
text += "↳ геолокация (в ответе)\n"
if message.location:
text += "↳ геолокация\n"
if replied and replied.poll:
text += "↳ опрос (в ответе)\n"
if message.poll:
text += "↳ опрос\n"
if replied and replied.voice:
text += "↳ голосовое сообщение (в ответе)\n"
if message.voice:
text += "↳ голосовое сообщение\n"
if replied and replied.text:
text += f"↳ {len(replied.text)} текст в ответе\n"
return text
def clean_tail_repeats(text: str, max_repeat: int = 10):
if not text:
return text, 0
original_length = len(text)
cleaned = text
pattern = rf"(.)\1{{{max_repeat},}}$"
def limit_repeats(match):
char = match.group(1)
return char * max_repeat
cleaned = re.sub(pattern, limit_repeats, cleaned)
pattern_space = rf"((\S)\s+)\2{{{max_repeat},}}$"
cleaned = re.sub(
pattern_space,
lambda m: (m.group(2) + " ") * min(max_repeat, len(m.group(1))),
cleaned,
)
words = cleaned.split()
if len(words) >= 2:
for i in range(1, min(len(words), 10)):
if all(words[-j] == words[-j - 1] for j in range(i)):
unique_words = words[: -(i + 1)]
cleaned = " ".join(unique_words + [words[-1]])
break
removed_count = original_length - len(cleaned)
cleaned = re.sub(r" +", " ", cleaned)
cleaned = cleaned.strip()
return cleaned, removed_count
def parse_response(text: str):
if "connection error." in text:
return {
"type": "connection",
"message": "ошибка подключения к провайдеру. подожди или смени провайдера в настройках узбекгпт.",
}
elif "model quota exceeded" in text:
return {
"type": "quota",
"message": "лимит токенов закончился. подожди или смени модель.",
}
elif "tier capacity exceeded." in text:
return {"type": "tier", "message": "попробуй ещё раз!"}
elif "internal server" in text:
return {
"type": "int",
"message": "произошла ошибка на стороне провайдера. подожди или смени провайдера в настройках узбекгпт.",
}
elif "(incomplete chunked read)" in text:
return {
"type": "incomplete",
"message": "сервер петух и оборвал соединение. подожди или смени провайдера в настройках узбекгпт.",
}
elif "provider error" in text:
return {
"type": "provider",
"message": "врат ошибка на стороне провайдера модели. смени провайдера или модель.",
}
elif "rate limit" in text:
return {
"type": "quota",
"message": "лимит токенов закончился у провайдера врат. подожди или смени модель.",
}
else:
return {
"type": "unknown",
"message": f"произошла какая-то ошибка при генерации... {text}",
}
def galockinator(text):
for _ in range(random.randint(1, 3)):
if random.random() < 0.3:
text += "☝️"
else:
text += "✅"
return text
def remove_think_tags(text):
result = re.sub(r"<think>.*?</think>", "", text, flags=re.DOTALL)
result = re.sub(r"<thought>.*?</thought>", "", text, flags=re.DOTALL)
return result
def get_all_users(only_notify=False):
with shelve.open("users") as db:
return {k: db[k] for k in db.keys() if not only_notify or db[k].get("notify") == "da"}
def get_all_user_ids(only_notify=False):
ids = []
with shelve.open("users") as db:
for user_id in db.keys():
if only_notify and db[user_id].get("notify") != "da":
continue
try:
ids.append(int(user_id))
except ValueError:
pass
return ids
def set_user_config(
user_id,
model_name,
stream=DEFAULT_STREAM,
call=DEFAULT_CALL,
prompt=DEFAULT_PROMPT,
notify=DEFAULT_NOTIFY,
markdown=DEFAULT_MARKDOWN,
prompts={},
):
with shelve.open("users") as db:
db[str(user_id)] = {
"model": model_name,
"stream": stream,
"call": call,
"prompt": prompt,
"notify": notify,
"markdown": markdown,
"prompts": prompts,
}
def set_user_setting(
user_id,
model=None,
stream=None,
call=None,
prompt=None,
notify=None,
markdown=None,
prompts=None,
):
with shelve.open("users") as db:
user_id = str(user_id)
if user_id not in db:
db[user_id] = {}
settings = db[user_id]
if model is not None: settings["model"] = model
if stream is not None: settings["stream"] = stream
if call is not None: settings["call"] = call
if prompt is not None: settings["prompt"] = prompt
if notify is not None: settings["notify"] = notify
if markdown is not None: settings["markdown"] = markdown
if prompts is not None: settings["prompts"] = prompts
db[user_id] = settings
def delete_user_from_db(user_id):
with shelve.open("users") as db:
if str(user_id) in db:
del db[str(user_id)]
def reset_user_setting(user_id, key, value):
with shelve.open("users") as db:
user = db[str(user_id)]
user[key] = value
db[str(user_id)] = user
def ensure_user(
user_id,
model_name=DEFAULT_MODEL,
stream_mode=DEFAULT_STREAM,
call_mode=DEFAULT_CALL,
prompt_name=DEFAULT_PROMPT,
notify_mode=DEFAULT_NOTIFY,
markdown=DEFAULT_MARKDOWN,
prompts={},
):
with shelve.open("users") as db:
key = str(user_id)
if key not in db:
db[key] = {
"model": model_name,
"stream": stream_mode,
"call": call_mode,
"prompt": prompt_name,
"notify": notify_mode,
"markdown": markdown,
"prompts": prompts,
}
def get_user_config(user_id):
with shelve.open("users") as db:
config = db.get(str(user_id), {})
defaults = {
"model": DEFAULT_MODEL,
"stream": DEFAULT_STREAM,
"call": DEFAULT_CALL,
"prompt": DEFAULT_PROMPT,
"notify": DEFAULT_NOTIFY,
"markdown": DEFAULT_MARKDOWN,
"prompts": {},
}
updated = False
for key, value in defaults.items():
if key not in config:
config[key] = value
updated = True
if updated:
db[str(user_id)] = config
return config
+156
View File
@@ -0,0 +1,156 @@
import string
from random import choices
from vars import *
from config import *
from helpers import get_user_config, set_user_setting
from aiogram.types import (
InlineKeyboardButton,
InlineKeyboardMarkup,
InlineQueryResultArticle,
InputTextMessageContent,
Message,
)
async def da(bot, message, user_id):
config = get_user_config(user_id)
print(config)
if user_id in alo_command:
if message.chat.id == alo_command[user_id]["chat_id"]:
if alo_command[user_id]["action"] == "p_name":
alo_command[user_id]["action"] = "p_prompt"
alo_command[user_id]["name"] = message.text[:16]
return await bot.edit_message_text(
text=f"установи промпт для `{alo_command[user_id]['name']}`:",
chat_id=alo_command[user_id]["chat_id"],
message_id=alo_command[user_id]["message_id"],
reply_markup=InlineKeyboardMarkup(
inline_keyboard=[
[
InlineKeyboardButton(
text=f"❌ отменить", callback_data=f"p_cancel%{user_id}"
),
],
]
)
)
elif alo_command[user_id]["action"] == "p_prompt":
alo_command[user_id]["action"] = None
alo_command[user_id]["prompt"] = message.text
if len(config["prompts"]) >= MAX_PROMPTS:
return await bot.edit_message_text(
text=f"невозможно создать новый промпт так как ты превысил лимит промптов da.",
chat_id=alo_command[user_id]["chat_id"],
message_id=alo_command[user_id]["message_id"],
reply_markup=InlineKeyboardMarkup(
inline_keyboard=[
[
InlineKeyboardButton(
text=f"ок", callback_data=f"user_prompts%{user_id}"
),
],
]
)
)
while 1:
alo_command[user_id]["id"] = ''.join(choices(string.ascii_letters, k=10))
if alo_command[user_id]["id"] not in config["prompts"]:
break
config["prompts"] = config["prompts"] | {
alo_command[user_id]["id"]: {
"name": alo_command[user_id]["name"],
"text": alo_command[user_id]["prompt"],
"filer": False,
"public": False
}
}
set_user_setting(
user_id,
prompts=config["prompts"]
)
return await bot.edit_message_text(
text=f"промпт `{alo_command[user_id]['name']}` создан!",
chat_id=alo_command[user_id]["chat_id"],
message_id=alo_command[user_id]["message_id"],
reply_markup=InlineKeyboardMarkup(
inline_keyboard=[
[
InlineKeyboardButton(
text=f"✅ посмотреть", callback_data=f"vp%{user_id}%{alo_command[user_id]['id']}"
),
],
]
)
)
elif alo_command[user_id]["action"] == "p_e_name":
alo_command[user_id]["action"] = None
alo_command[user_id]["name"] = message.text[:16]
config["prompts"] = config["prompts"] | {
alo_command[user_id]["prompt_id"]: {
"name": alo_command[user_id]["name"],
"text": config["prompts"][alo_command[user_id]["prompt_id"]]["text"],
"filer": config["prompts"][alo_command[user_id]["prompt_id"]]["filer"],
"public": config["prompts"][alo_command[user_id]["prompt_id"]]["public"],
}
}
set_user_setting(
user_id,
prompts = config["prompts"]
)
return await bot.edit_message_text(
text=f"имя промпта было изменено на `{alo_command[user_id]['name']}`.",
chat_id=alo_command[user_id]["chat_id"],
message_id=alo_command[user_id]["message_id"],
reply_markup=InlineKeyboardMarkup(
inline_keyboard=[
[
InlineKeyboardButton(
text=f"✅ посмотреть", callback_data=f"vp%{user_id}%{alo_command[user_id]['prompt_id']}"
),
],
]
)
)
elif alo_command[user_id]["action"] == "p_e_prompt":
alo_command[user_id]["action"] = None
alo_command[user_id]["prompt"] = message.text
config["prompts"] = config["prompts"] | {
alo_command[user_id]["prompt_id"]: {
"name": config["prompts"][alo_command[user_id]["prompt_id"]]["name"],
"text": alo_command[user_id]["prompt"],
"filer": config["prompts"][alo_command[user_id]["prompt_id"]]["filer"],
"public": config["prompts"][alo_command[user_id]["prompt_id"]]["public"],
}
}
set_user_setting(
user_id,
prompts=config["prompts"]
)
return await bot.edit_message_text(
text=f"текст промпта был изменён.",
chat_id=alo_command[user_id]["chat_id"],
message_id=alo_command[user_id]["message_id"],
reply_markup=InlineKeyboardMarkup(
inline_keyboard=[
[
InlineKeyboardButton(
text=f"✅ посмотреть", callback_data=f"vp%{user_id}%{alo_command[user_id]['prompt_id']}"
),
],
]
)
)
return None
+86 -182
View File
@@ -4,9 +4,9 @@ import base64
import io import io
import sys import sys
import time import time
import string
import gconfig import gconfig
import input_msg
# from aiogram.methods import SendMessageDraft # from aiogram.methods import SendMessageDraft
from datetime import datetime from datetime import datetime
@@ -36,6 +36,7 @@ from callbacks import *
from statistics import * from statistics import *
from colors import * from colors import *
from helpers import * from helpers import *
from vars import *
from commands import * from commands import *
from dotenv import load_dotenv from dotenv import load_dotenv
from random import uniform, shuffle, choices from random import uniform, shuffle, choices
@@ -90,163 +91,9 @@ async def guest_middleware(handler, event, data):
config = get_user_config(user_id) config = get_user_config(user_id)
prompts = SYSTEM_PROMPTS | config["prompts"] prompts = SYSTEM_PROMPTS | config["prompts"]
p = prompts[config["prompt"]] p = prompts[config["prompt"]]
# внимание внизу самая умная система осторожнеее!!1!1
if user_id in alo_command:
if message.chat.id == alo_command[user_id]["chat_id"]:
if alo_command[user_id]["action"] == "p_name":
alo_command[user_id]["action"] = "p_prompt"
alo_command[user_id]["name"] = message.text[:16]
return await bot.edit_message_text(
text=f"установи промпт для `{alo_command[user_id]['name']}`:",
chat_id=alo_command[user_id]["chat_id"],
message_id=alo_command[user_id]["message_id"],
reply_markup=InlineKeyboardMarkup(
inline_keyboard=[
[
InlineKeyboardButton(
text=f"❌ отменить", callback_data=f"p_cancel%{user_id}"
),
],
]
)
)
elif alo_command[user_id]["action"] == "p_prompt":
alo_command[user_id]["action"] = None
alo_command[user_id]["prompt"] = message.text
if len(config["prompts"]) >= MAX_PROMPTS: if await input_msg.da(bot, message, user_id) != None:
return await bot.edit_message_text( return
text=f"невозможно создать новый промпт так как ты превысил лимит промптов da.",
chat_id=alo_command[user_id]["chat_id"],
message_id=alo_command[user_id]["message_id"],
reply_markup=InlineKeyboardMarkup(
inline_keyboard=[
[
InlineKeyboardButton(
text=f"ок", callback_data=f"user_prompts%{user_id}"
),
],
]
)
)
while 1:
alo_command[user_id]["id"] = ''.join(choices(string.ascii_letters, k=10))
if alo_command[user_id]["id"] not in config["prompts"]:
break
config["prompts"] = config["prompts"] | {
alo_command[user_id]["id"]: {
"name": alo_command[user_id]["name"],
"text": alo_command[user_id]["prompt"],
"filer": False,
"public": False
}
}
set_user_config(
user_id,
config.get("model"),
config.get("stream", True),
config.get("call"),
config.get("prompt"),
config.get("notify"),
config.get("markdown"),
config["prompts"]
)
return await bot.edit_message_text(
text=f"промпт `{alo_command[user_id]['name']}` создан!",
chat_id=alo_command[user_id]["chat_id"],
message_id=alo_command[user_id]["message_id"],
reply_markup=InlineKeyboardMarkup(
inline_keyboard=[
[
InlineKeyboardButton(
text=f"✅ посмотреть", callback_data=f"vp%{user_id}%{alo_command[user_id]['id']}"
),
],
]
)
)
elif alo_command[user_id]["action"] == "p_e_name":
alo_command[user_id]["action"] = None
alo_command[user_id]["name"] = message.text[:16]
config["prompts"] = config["prompts"] | {
alo_command[user_id]["prompt_id"]: {
"name": alo_command[user_id]["name"],
"text": config["prompts"][alo_command[user_id]["prompt_id"]]["text"],
"filer": config["prompts"][alo_command[user_id]["prompt_id"]]["filer"],
"public": config["prompts"][alo_command[user_id]["prompt_id"]]["public"],
}
}
set_user_config(
user_id,
config.get("model"),
config.get("stream", True),
config.get("call"),
config.get("prompt"),
config.get("notify"),
config.get("markdown"),
config["prompts"]
)
return await bot.edit_message_text(
text=f"имя промпта было изменено на `{alo_command[user_id]['name']}`.",
chat_id=alo_command[user_id]["chat_id"],
message_id=alo_command[user_id]["message_id"],
reply_markup=InlineKeyboardMarkup(
inline_keyboard=[
[
InlineKeyboardButton(
text=f"✅ посмотреть", callback_data=f"vp%{user_id}%{alo_command[user_id]['prompt_id']}"
),
],
]
)
)
elif alo_command[user_id]["action"] == "p_e_prompt":
alo_command[user_id]["action"] = None
alo_command[user_id]["prompt"] = message.text
config["prompts"] = config["prompts"] | {
alo_command[user_id]["prompt_id"]: {
"name": config["prompts"][alo_command[user_id]["prompt_id"]]["name"],
"text": alo_command[user_id]["prompt"],
"filer": config["prompts"][alo_command[user_id]["prompt_id"]]["filer"],
"public": config["prompts"][alo_command[user_id]["prompt_id"]]["public"],
}
}
set_user_config(
user_id,
config.get("model"),
config.get("stream", True),
config.get("call"),
config.get("prompt"),
config.get("notify"),
config.get("markdown"),
config["prompts"]
)
return await bot.edit_message_text(
text=f"текст промпта был изменён.",
chat_id=alo_command[user_id]["chat_id"],
message_id=alo_command[user_id]["message_id"],
reply_markup=InlineKeyboardMarkup(
inline_keyboard=[
[
InlineKeyboardButton(
text=f"✅ посмотреть", callback_data=f"vp%{user_id}%{alo_command[user_id]['prompt_id']}"
),
],
]
)
)
if p["filer"]: if p["filer"]:
if event.guest_message: if event.guest_message:
@@ -294,7 +141,7 @@ async def guest_middleware(handler, event, data):
last_command_time[user_id][1] = True last_command_time[user_id][1] = True
last_command_time[user_id][2] += [message.message_id] last_command_time[user_id][2] += [message.message_id]
await asyncio.sleep(uniform(0,0.5)) await asyncio.sleep(uniform(0,0.2))
if event.message: if event.message:
try: try:
@@ -314,12 +161,27 @@ async def guest_middleware(handler, event, data):
voice = None voice = None
model = config["model"].split("*", 1)
if VOSK_API != "": if VOSK_API != "":
if message.voice: if message.voice:
voice = message.voice voice = message.voice
elif replied and replied.voice: elif replied and replied.voice:
voice = replied.voice voice = replied.voice
process = {
"text": "wait",
"photo_a": "wait" if replied and replied.photo and MODELS[model[0]].get("vision", False) == False else None,
"photo": "wait" if message.photo and MODELS[model[0]][model[1]].get("vision", False) == False else None,
"stt": "wait" if voice else None,
}
if event.message:
if (config["stream"] == "edit") or (config["stream"] == "native" and user_id == message.chat.id):
msg = await message.reply(make_graph(message, process))
else:
gmsg = await g_answer(message, make_graph(message, process))
location = None location = None
if message.location: if message.location:
location = message.location location = message.location
@@ -339,7 +201,7 @@ async def guest_middleware(handler, event, data):
try: try:
brat = await bot.download(voice, destination=buf) brat = await bot.download(voice, destination=buf)
except Exception as e: except Exception as e:
print(f"{YELLOW} -- voice err - {e}{RESET}") print(f"{YELLOW} -- voice download err - {e}{RESET}")
buf.seek(0) buf.seek(0)
try: try:
@@ -349,6 +211,12 @@ async def guest_middleware(handler, event, data):
buf.read() buf.read()
) )
except Exception as e: except Exception as e:
process["stt"] = "error"
if event.message and msg:
await msg.edit_text(make_graph(message, process))
elif event.guest_message and gmsg:
await bot.edit_message_text(text=make_graph(message, process), inline_message_id=gmsg.inline_message_id)
prompt = f"<голосовое сообщение>ошибка подключения к api stt</голосовое сообщение>{prompt}" prompt = f"<голосовое сообщение>ошибка подключения к api stt</голосовое сообщение>{prompt}"
print(f"{RED} -- voice err - {e}{RESET}") print(f"{RED} -- voice err - {e}{RESET}")
else: else:
@@ -356,17 +224,15 @@ async def guest_middleware(handler, event, data):
if message.document: if message.document:
if message.document.file_size > 4096:
await mans(message, "слишком много данных не хочу отвечать☝️☝️")
return
file_bytes = io.BytesIO() file_bytes = io.BytesIO()
try: try:
await bot.download(message.document, destination=file_bytes) await bot.download(message.document, destination=file_bytes)
file_bytes.seek(0) file_bytes.seek(0)
file_content = file_bytes.read().decode("utf-8", errors="ignore") if message.document.file_size > 9000:
file_content = file_bytes.read().decode("utf-8", errors="ignore")[:9000]
else:
file_content = file_bytes.read().decode("utf-8", errors="ignore")
file_bytes.close() file_bytes.close()
prompt = f"<файл>{file_content}</файл>{prompt}" prompt = f"<файл>{file_content}</файл>{prompt}"
@@ -376,20 +242,20 @@ async def guest_middleware(handler, event, data):
return return
except Exception: except Exception:
await mans(message, "файл не вошёл ало ошибка❌❌") if msg:
await msg.edit_text(message, "файл не вошёл ало ошибка❌❌")
return return
if replied and replied.document: if replied and replied.document:
if replied.document.file_size > 4096:
await mans(message, "слишком много данных не хочу отвечать☝️☝️")
return
file_bytes = io.BytesIO() file_bytes = io.BytesIO()
try: try:
await bot.download(replied.document, destination=file_bytes) await bot.download(replied.document, destination=file_bytes)
file_bytes.seek(0) file_bytes.seek(0)
file_content = file_bytes.read().decode("utf-8", errors="ignore") if replied.document.file_size > 9000:
file_content = file_bytes.read().decode("utf-8", errors="ignore")[:9000]
else:
file_content = file_bytes.read().decode("utf-8", errors="ignore")
file_bytes.close()
prompt = f"<файл>{file_content}</файл>{prompt}" prompt = f"<файл>{file_content}</файл>{prompt}"
except UnicodeDecodeError: except UnicodeDecodeError:
await mans(message, "файл не вошёл❌") await mans(message, "файл не вошёл❌")
@@ -433,23 +299,30 @@ async def guest_middleware(handler, event, data):
file_bytes = await bot.download(photo) file_bytes = await bot.download(photo)
image_bytes = file_bytes.read() image_bytes = file_bytes.read()
b64_image = base64.b64encode(image_bytes).decode("utf-8") b64_image = base64.b64encode(image_bytes).decode("utf-8")
images += [b64_image] images += [{"data": b64_image, "process": "photo_a"}]
except Exception as e: except Exception as e:
process["photo_a"] = "error"
if event.message and msg:
await msg.edit_text(make_graph(message, process))
elif event.guest_message and gmsg:
await bot.edit_message_text(text=make_graph(message, process), inline_message_id=gmsg.inline_message_id)
print(f"{RED} -- photo - {e}{RESET}") print(f"{RED} -- photo - {e}{RESET}")
if message.photo and IMAGE_MODEL != "": if message.photo and IMAGE_MODEL != "":
try: try:
if event.message:
if not msg:
msg = await message.reply("👀")
photo = message.photo[-1] photo = message.photo[-1]
file_bytes = await bot.download(photo) file_bytes = await bot.download(photo)
image_bytes = file_bytes.read() image_bytes = file_bytes.read()
b64_image = base64.b64encode(image_bytes).decode("utf-8") b64_image = base64.b64encode(image_bytes).decode("utf-8")
images += [b64_image] images += [{"data": b64_image, "process": "photo"}]
except Exception as e: except Exception as e:
process["photo"] = "error"
if event.message and msg:
await msg.edit_text(make_graph(message, process))
elif event.guest_message and gmsg:
await bot.edit_message_text(text=make_graph(message, process), inline_message_id=gmsg.inline_message_id)
print(f"{RED} -- photo - {e}{RESET}") print(f"{RED} -- photo - {e}{RESET}")
prompt = f"{prompt}\n{user_text}" prompt = f"{prompt}\n{user_text}"
if replied_text: if replied_text:
prompt = f"<ответ на>{replied_text}</ответ> {prompt}" prompt = f"<ответ на>{replied_text}</ответ> {prompt}"
@@ -475,7 +348,10 @@ async def guest_middleware(handler, event, data):
] ]
) )
if event.guest_message: if event.guest_message:
await g_answer(message, alloh_one_text, reply_markup=reply_markup_url) if gmsg:
await bot.edit_message_text(text=alloh_one_text, inline_message_id=gmsg.inline_message_id, reply_markup=reply_markup_url)
else:
await g_answer(message, alloh_one_text, reply_markup=reply_markup_url)
elif event.message: elif event.message:
await message.reply_rich(InputRichMessage(markdown="# новый крутой стилёк\n*da*\n```\nтестовое сообщение врат\n```")) await message.reply_rich(InputRichMessage(markdown="# новый крутой стилёк\n*da*\n```\nтестовое сообщение врат\n```"))
await message.answer(alloh_text, reply_markup=reply_markup) await message.answer(alloh_text, reply_markup=reply_markup)
@@ -489,10 +365,12 @@ async def guest_middleware(handler, event, data):
if stream == "edit": if stream == "edit":
if event.message: if event.message:
im_model = IMAGE_MODEL.split("*", 1)
tx_model = config["model"].split("*", 1)
if msg: if msg:
message_id = msg.message_id message_id = msg.message_id
else: else:
msg = await message.reply("💬") msg = await message.reply("💭")
message_id = msg.message_id message_id = msg.message_id
elif event.guest_message: elif event.guest_message:
stream = "none" stream = "none"
@@ -517,6 +395,9 @@ async def guest_middleware(handler, event, data):
user_id=user_id, user_id=user_id,
message_id=message_id, message_id=message_id,
images=images, images=images,
msg=msg,
process=process,
message=message
) )
else: else:
result = await generate( result = await generate(
@@ -526,6 +407,7 @@ async def guest_middleware(handler, event, data):
user_id=user_id, user_id=user_id,
message_id=None, message_id=None,
images=images, images=images,
inline_id=gmsg.inline_message_id
) )
result = parse_tools(result) result = parse_tools(result)
@@ -633,8 +515,23 @@ async def guest_middleware(handler, event, data):
try: try:
if event.guest_message: if event.guest_message:
await g_answer(message, result, user_id=user_id) if len(result) > 4000:
result = result[:4000] + "...\n\n__сообщение твой большой и он сокращен__"
if gmsg:
await bot.edit_message_text(text=result, inline_message_id=gmsg.inline_message_id)
else:
await g_answer(message, result, user_id=user_id)
elif event.message: elif event.message:
if len(result) > 4000:
if msg:
await msg.delete()
file = BufferedInputFile(
file=result.encode("utf-8"),
filename=result.replace("\n", "").replace(" ", "_")[:5] + ".txt"
)
return await message.reply_document(
document=file
)
if msg: if msg:
if stream == "native": if stream == "native":
await msg.delete() await msg.delete()
@@ -653,7 +550,12 @@ async def guest_middleware(handler, event, data):
kwargs["parse_mode"] = None kwargs["parse_mode"] = None
try: try:
if event.guest_message: if event.guest_message:
await g_answer(message, result) if len(result) > 4000:
result = result[:4000] + "...\n\n__сообщение твой большой и он сокращен__"
if gmsg:
await bot.edit_message_text(text=result, inline_message_id=gmsg.inline_message_id, parse_mode="None")
else:
await g_answer(message, result, parse_mode="None")
elif event.message: elif event.message:
if msg: if msg:
if stream == "native": if stream == "native":
@@ -777,6 +679,7 @@ async def chosen_inline_result_handler(chosen_result: ChosenInlineResult):
await bot.edit_message_text( await bot.edit_message_text(
text=error["message"], text=error["message"],
inline_message_id=inline_message_id, inline_message_id=inline_message_id,
parse_mode=None
) )
print(f"{RED} -- {error['type']} -- {error['message']}") print(f"{RED} -- {error['type']} -- {error['message']}")
return return
@@ -823,3 +726,4 @@ async def main():
if __name__ == "__main__": if __name__ == "__main__":
asyncio.run(main()) asyncio.run(main())
-1
View File
@@ -2,4 +2,3 @@ aiogram==3.29.1
python-dotenv==1.2.1 python-dotenv==1.2.1
pillow==12.0.0 pillow==12.0.0
requests requests
openai
+116 -263
View File
@@ -2,233 +2,24 @@ import random
import re import re
import shelve import shelve
import time import time
import ai
import json
from configparser import DEFAULTSECT from configparser import DEFAULTSECT
from pprint import pprint from pprint import pprint
from openai import AsyncOpenAI
from statistics import * from statistics import *
from colors import * from colors import *
from helpers import *
from config import * from config import *
from vars import *
last_command_time = {} from aiogram.exceptions import TelegramBadRequest, TelegramForbiddenError
last_error_time = {}
last_block_time = {}
alo_command = {}
user_contexts = {}
def get_clients():
provs = {}
for provider, settings in PROVIDERS.items():
if settings.get("module") == "openai":
provs[provider] = AsyncOpenAI(
base_url=settings.get("url"), api_key=settings.get("key")
)
return provs
providers = get_clients()
def clean_tail_repeats(text: str, max_repeat: int = 10):
if not text:
return text, 0
original_length = len(text)
cleaned = text
pattern = rf"(.)\1{{{max_repeat},}}$"
def limit_repeats(match):
char = match.group(1)
return char * max_repeat
cleaned = re.sub(pattern, limit_repeats, cleaned)
pattern_space = rf"((\S)\s+)\2{{{max_repeat},}}$"
cleaned = re.sub(
pattern_space,
lambda m: (m.group(2) + " ") * min(max_repeat, len(m.group(1))),
cleaned,
)
words = cleaned.split()
if len(words) >= 2:
for i in range(1, min(len(words), 10)):
if all(words[-j] == words[-j - 1] for j in range(i)):
unique_words = words[: -(i + 1)]
cleaned = " ".join(unique_words + [words[-1]])
break
removed_count = original_length - len(cleaned)
cleaned = re.sub(r" +", " ", cleaned)
cleaned = cleaned.strip()
return cleaned, removed_count
def parse_response(text: str):
if "connection error." in text:
return {
"type": "connection",
"message": "ошибка подключения к провайдеру. подожди или смени провайдера в настройках узбекгпт.",
}
elif "model quota exceeded" in text:
return {
"type": "quota",
"message": "лимит токенов закончился. подожди или смени модель.",
}
elif "tier capacity exceeded." in text:
return {"type": "tier", "message": "попробуй ещё раз!"}
elif "internal server" in text:
return {
"type": "int",
"message": "произошла ошибка на стороне провайдера. подожди или смени провайдера в настройках узбекгпт.",
}
elif "(incomplete chunked read)" in text:
return {
"type": "incomplete",
"message": "сервер петух и оборвал соединение. подожди или смени провайдера в настройках узбекгпт.",
}
elif "provider error" in text:
return {
"type": "provider",
"message": "врат ошибка на стороне провайдера модели. смени провайдера или модель.",
}
elif "rate limit" in text:
return {
"type": "quota",
"message": "лимит токенов закончился у провайдера врат. подожди или смени модель.",
}
else:
return {
"type": "unknown",
"message": f"произошла какая-то ошибка при генерации... {text}",
}
def galockinator(text):
for _ in range(random.randint(1, 3)):
if random.random() < 0.3:
text += "☝️"
else:
text += "✅"
return text
def remove_think_tags(text):
result = re.sub(r"<think>.*?</think>", "", text, flags=re.DOTALL)
result = re.sub(r"<thought>.*?</thought>", "", text, flags=re.DOTALL)
return result
def get_all_users(only_notify=False):
with shelve.open("users") as db:
return {k: db[k] for k in db.keys() if not only_notify or db[k].get("notify") == "da"}
def get_all_user_ids(only_notify=False):
ids = []
with shelve.open("users") as db:
for user_id in db.keys():
if only_notify and db[user_id].get("notify") != "da":
continue
try:
ids.append(int(user_id))
except ValueError:
pass
return ids
def set_user_config(
user_id,
model_name,
stream_mode=DEFAULT_STREAM,
call_mode=DEFAULT_CALL,
prompt_name=DEFAULT_PROMPT,
notify_mode=DEFAULT_NOTIFY,
markdown=DEFAULT_MARKDOWN,
prompts={},
):
with shelve.open("users") as db:
db[str(user_id)] = {
"model": model_name,
"stream": stream_mode,
"call": call_mode,
"prompt": prompt_name,
"notify": notify_mode,
"markdown": markdown,
"prompts": prompts,
}
def delete_user_from_db(user_id):
with shelve.open("users") as db:
if str(user_id) in db:
del db[str(user_id)]
def reset_user_setting(user_id, key, value):
with shelve.open("users") as db:
user = db[str(user_id)]
user[key] = value
db[str(user_id)] = user
def ensure_user(
user_id,
model_name=DEFAULT_MODEL,
stream_mode=DEFAULT_STREAM,
call_mode=DEFAULT_CALL,
prompt_name=DEFAULT_PROMPT,
notify_mode=DEFAULT_NOTIFY,
markdown=DEFAULT_MARKDOWN,
prompts={},
):
with shelve.open("users") as db:
key = str(user_id)
if key not in db:
db[key] = {
"model": model_name,
"stream": stream_mode,
"call": call_mode,
"prompt": prompt_name,
"notify": notify_mode,
"markdown": markdown,
"prompts": prompts,
}
def get_user_config(user_id):
with shelve.open("users") as db:
config = db.get(str(user_id), {})
defaults = {
"model": DEFAULT_MODEL,
"stream": DEFAULT_STREAM,
"call": DEFAULT_CALL,
"prompt": DEFAULT_PROMPT,
"notify": DEFAULT_NOTIFY,
"markdown": DEFAULT_MARKDOWN,
"prompts": {},
}
updated = False
for key, value in defaults.items():
if key not in config:
config[key] = value
updated = True
if updated:
db[str(user_id)] = config
return config
async def generate( async def generate(
prompt: str, bot=None, user_id=None, chat_id=None, message_id=None, images=None prompt: str, bot=None, user_id=None, chat_id=None, message_id=None, images=None, msg=None, process=None, message=None, inline_id=None
) -> str: ) -> str:
if user_id: if user_id:
if user_id not in user_contexts: if user_id not in user_contexts:
@@ -265,9 +56,11 @@ async def generate(
f"2. конфиг бота настроен неправильно и надо связаться с тем кто его хостит" f"2. конфиг бота настроен неправильно и надо связаться с тем кто его хостит"
return text return text
if stream_cf == "native" and user_id == chat_id and settings.get("nostream") == False: if stream_cf == "native" and user_id == chat_id and settings.get("nostream", False) == False:
stream = True stream = True
elif stream_cf == "edit" and chat_id and message_id and settings.get("nostream") == False: elif stream_cf == "edit" and chat_id and message_id and settings.get("nostream", False) == False:
stream = True
elif stream_cf == "edit" or stream_cf == "native" and inline_id:
stream = True stream = True
else: else:
stream = False stream = False
@@ -281,10 +74,20 @@ async def generate(
else: else:
for image in images: for image in images:
try: try:
image_text = await image2text(image) if process and msg and message:
process[image["process"]] = "make"
await msg.edit_text(make_graph(message, process))
image_text = await image2text(image["data"])
prompt = f"<фото>{image_text}</фото>\n{prompt}" prompt = f"<фото>{image_text}</фото>\n{prompt}"
except Exception as e: except Exception as e:
if process and msg and message:
process[image["process"]] = "error"
await msg.edit_text(make_graph(message, process))
print(f"{RED} -- err photo - {e} : {config.get('model', '')}{RESET}") print(f"{RED} -- err photo - {e} : {config.get('model', '')}{RESET}")
else:
if process and msg and message:
process[image["process"]] = "done"
await msg.edit_text(make_graph(message, process))
content += [{"type": "text", "text": prompt}] content += [{"type": "text", "text": prompt}]
@@ -322,15 +125,19 @@ async def generate(
add_one_to("stats/gens") add_one_to("stats/gens")
try: try:
client = providers[model[0]] provider = PROVIDERS[model[0]]
except Exception: except Exception:
text = "❌произошла ошибка, возможные проблемы:\n" \ text = "❌произошла ошибка, возможные проблемы:\n" \
"1. у вас выбрана удалённая модель или провайдер\n" \ "1. у вас выбрана удалённая модель или провайдер\n" \
"2. конфиг бота настроен неправильно и надо связаться с тем кто его хостит" "2. конфиг бота настроен неправильно и надо связаться с тем кто его хостит"
return text return text
if process and msg and message:
process["text"] = "make"
await msg.edit_text(make_graph(message, process))
text = await openai_generate_text( text = await openai_generate_text(
oai=client, api=provider,
bot=bot, bot=bot,
model=model[1], model=model[1],
settings=settings, settings=settings,
@@ -340,6 +147,7 @@ async def generate(
chat_id=chat_id, chat_id=chat_id,
draft_id=chat_id, draft_id=chat_id,
message_id=message_id, message_id=message_id,
inline_id=inline_id
) )
if user_id: if user_id:
@@ -352,8 +160,8 @@ async def generate(
async def image2text(image) -> str: async def image2text(image) -> str:
if IMAGE_MODEL == "": if IMAGE_MODEL == "":
return "" return ""
model = IMAGE_MODEL.split("*", 2) model = IMAGE_MODEL.split("*", 1)
client = providers[model[0]] api = PROVIDERS[model[0]]
text = "" text = ""
messages = [ messages = [
{ {
@@ -364,24 +172,26 @@ async def image2text(image) -> str:
], ],
} }
] ]
response = await client.responses.create( async for response in ai.responses(
model=model[1], input=messages, stream=False url=api["url"], api_key=api["key"], model=model[1], input=messages, stream=False
) ):
pass
text = response.output_text text = response.output_text
return text return text
async def openai_generate_text( async def openai_generate_text(
oai: AsyncOpenAI, api,
bot, bot,
model, model,
settings, settings,
messages, messages,
stream, stream,
stream_cf, stream_cf,
chat_id, chat_id=None,
draft_id, draft_id=None,
message_id, message_id=None,
inline_id=None
) -> str: ) -> str:
try: try:
extra_body = { extra_body = {
@@ -390,55 +200,98 @@ async def openai_generate_text(
if settings.get("noexb"): if settings.get("noexb"):
extra_body = None extra_body = None
completion = await oai.chat.completions.create( alo = {
model=model, "url": api["url"],
messages=messages, "api_key": api["key"],
stream=stream, "model": model,
max_tokens=MAX_TOKENS, "messages": messages,
extra_body=extra_body "stream": stream,
) "max_tokens": MAX_TOKENS,
"extra": extra_body
}
if stream: if stream:
message = "" message = ""
t_counter = 0
counter = 0 counter = 0
counter_2 = 1
if not draft_id: if not draft_id:
draft_id = chat_id draft_id = chat_id
async for event in completion: async for chunk in ai.completions(**alo):
content = event.choices[0].delta.content # chunk = json.loads(chunk)
try:
content = chunk["choices"][0]["delta"]["content"]
except:
continue
if content: if content:
message += content message += content
counter += 1 counter += len(content)
if stream_cf == "native": t_counter += 1
counter_limit = settings.get("n_tok")
else:
counter_limit = settings.get("e_tok")
if counter % counter_limit == 0: if counter > MAX_SYMBOLS:
break
if int(counter / STREAMING_SPLIT_SYMBOLS) == counter_2:
counter_2 += 1
display_text, s = clean_tail_repeats(message) display_text, s = clean_tail_repeats(message)
if s > 0: if s > 0:
display_text += f"*... <{s} обрезано>*" display_text += f"*... <{s} обрезано>*"
if display_text.count("```") % 2 != 0: if display_text.count("```") % 2 != 0:
display_text += "\n```" display_text += "\n```"
try:
if stream_cf == "native": if counter < 3950:
await bot.send_message_draft( display_text += "▋"
chat_id=chat_id,
draft_id=draft_id, try:
text=display_text, if stream_cf == "native" and chat_id and draft_id:
parse_mode="Markdown", await bot.send_message_draft(
) chat_id=chat_id,
elif stream_cf == "edit": draft_id=draft_id,
await bot.edit_message_text( text=display_text,
chat_id=chat_id, )
message_id=message_id, elif stream_cf == "edit" and chat_id and message_id:
text=display_text, await bot.edit_message_text(
parse_mode="Markdown", chat_id=chat_id,
) message_id=message_id,
except Exception as e: text=display_text,
print(f"{YELLOW} -- {e}{RESET}") )
elif stream_cf == "edit" or stream_cf == "native" and inline_id:
await bot.edit_message_text(
inline_message_id=inline_id,
text=display_text,
)
except TelegramBadRequest as e:
if "can't parse entities" in str(e):
if stream_cf == "native" and chat_id and draft_id:
await bot.send_message_draft(
chat_id=chat_id,
draft_id=draft_id,
text=display_text,
parse_mode=None,
)
elif stream_cf == "edit" and chat_id and message_id:
await bot.edit_message_text(
chat_id=chat_id,
message_id=message_id,
text=display_text,
parse_mode=None,
)
elif stream_cf == "edit" or stream_cf == "native" and inline_id:
await bot.edit_message_text(
inline_message_id=inline_id,
text=display_text,
parse_mode=None,
)
else:
print(f"{YELLOW} -- {e}{RESET}")
except Exception as e:
print(f"{YELLOW} -- {e}{RESET}")
text = message text = message
else: else:
text = completion.choices[0].message.content async for completion in ai.completions(**alo):
pass
text = completion["choices"][0]["message"]["content"]
except Exception as e: except Exception as e:
error = parse_response(str(e).lower()) error = parse_response(str(e).lower())
print(f"{RED} -- {error['type']} - {e}{RESET}") print(f"{RED} -- {error['type']} - {e}{RESET}")
+5
View File
@@ -0,0 +1,5 @@
last_command_time = {}
last_error_time = {}
last_block_time = {}
alo_command = {}
user_contexts = {}