It's version 0.4
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
import base64
|
||||
import aiohttp
|
||||
import logging
|
||||
from aiogram import Dispatcher, Bot
|
||||
from aiogram.types import Message
|
||||
from utils.antispam import saving, save_message
|
||||
from aiogram.filters import Command
|
||||
from models.state import BotState
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def register_handlers(dp: Dispatcher, state: BotState, bot: Bot):
|
||||
chat_history = {}
|
||||
MAX_HISTORY = 20 # храним последние 20 сообщений (user+assistant)
|
||||
|
||||
@dp.message(Command("gpt"))
|
||||
@saving
|
||||
async def ask_gpt(message: Message):
|
||||
chat_id = message.chat.id
|
||||
if chat_id not in chat_history:
|
||||
chat_history[chat_id] = []
|
||||
|
||||
content_blocks = []
|
||||
user_prompt = None
|
||||
|
||||
# Текст после команды или caption
|
||||
if message.text:
|
||||
parts = message.text.split(maxsplit=1)
|
||||
if len(parts) > 1:
|
||||
user_prompt = parts[1]
|
||||
if message.caption:
|
||||
user_prompt = message.caption
|
||||
|
||||
if user_prompt:
|
||||
content_blocks.append({"type": "text", "text": user_prompt})
|
||||
|
||||
# Фото → base64 → image_url
|
||||
if message.photo:
|
||||
photo = message.photo[-1]
|
||||
file = await bot.get_file(photo.file_id)
|
||||
file_bytes = await bot.download_file(file.file_path)
|
||||
image_b64 = base64.b64encode(file_bytes.read()).decode("utf-8")
|
||||
content_blocks.append(
|
||||
{
|
||||
"type": "image_url",
|
||||
"image_url": {"url": f"data:image/jpeg;base64,{image_b64}"},
|
||||
}
|
||||
)
|
||||
|
||||
if not content_blocks:
|
||||
await message.reply("❗ Укажи текст или прикрепи фото")
|
||||
return
|
||||
|
||||
url = "http://192.168.31.197:1234/v1/chat/completions"
|
||||
|
||||
# Добавляем новое сообщение в историю
|
||||
chat_history[chat_id].append({"role": "user", "content": content_blocks})
|
||||
|
||||
# Ограничиваем историю (оставляем последние MAX_HISTORY сообщений)
|
||||
if len(chat_history[chat_id]) > MAX_HISTORY:
|
||||
chat_history[chat_id] = chat_history[chat_id][-MAX_HISTORY:]
|
||||
|
||||
payload = {
|
||||
"model": "qwen/qwen3-vl-4b",
|
||||
"messages": chat_history[ chat_id],
|
||||
"temperature": 0.7,
|
||||
"max_tokens": 4096,
|
||||
"stream": False,
|
||||
}
|
||||
|
||||
try:
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.post(url, json=payload) as resp:
|
||||
if resp.status != 200:
|
||||
error_text = await resp.text()
|
||||
await message.reply(
|
||||
f"❌ Ошибка LM Studio: {resp.status} {error_text}"
|
||||
)
|
||||
return
|
||||
|
||||
data = await resp.json()
|
||||
reply_text = data["choices"][0]["message"]["content"]
|
||||
|
||||
# Сохраняем ответ ассистента в историю
|
||||
chat_history[chat_id].append(
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": [{"type": "text", "text": reply_text}],
|
||||
}
|
||||
)
|
||||
|
||||
# Ограничиваем снова (чтобы не разрасталось)
|
||||
if len(chat_history[chat_id]) > MAX_HISTORY:
|
||||
chat_history[chat_id] = chat_history[chat_id][-MAX_HISTORY:]
|
||||
|
||||
msg = await message.reply(f"🤖 Ответ:\n{reply_text}")
|
||||
save_message(msg.chat.id, msg.message_id)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка при запросе к LM Studio: {e}")
|
||||
await message.reply(f"❌ Ошибка при запросе к LM Studio: {e}")
|
||||
|
||||
@dp.message(Command("clear"))
|
||||
async def clear(message: Message):
|
||||
chat_history.pop(message.chat.id, None)
|
||||
Reference in New Issue
Block a user