from .. import loader, utils import requests import io import aiohttp import logging logger = logging.getLogger(__name__) # meta developer: @kmodules # changelog: Фиксы, обновитесь обязательно __version__ = (1, 5, 4) version = __version__ @loader.tds class KsenonGPTMod(loader.Module): """KsenonGPT module for text and image generation using KsenonAPI""" strings = { "name": "KsenonGPT", "no_api_key": "⚠️ You have not set up the API key!\n\n🌐 The key is very easy to get, it's free.\n\n🔓 Bot: @ksenonapi_gettoken_bot", "generating_text": "💬 Responding to your message...", "text_generated": "💬 Request: {}\n\n💬 {}", "generating_image": "🖼 Generating image...\n\n🤖 Model: {}\n🔗 Request: {}", "image_generated": "🖼 Image generated!\n\n🤖 Model: {}\n🔗 Request: {}\n\n📥 Link: {}", "error_blocked": "🔒 You have been blocked!\n\n🗑NSFW | politics etc. generation is prohibited.", "error_occurred": "⚠️ An error occurred!\n\n💻 Model: {}\n📶 Server status, code: {}\n➡️ Error: {}", "text_models": "🌐 Text models:\n\n
o1-preview\ngpt-4o\nclaude-3-5-sonnet\nsearchgpt (GPT + Internet)\nblackboxai-pro\nclaude-3-5-sonnet-20240620\nclaude-3-haiku-ddg\ngemini-1.5-pro-latest\nllama-3.1-405b\ngpt-3.5-turbo-202201\ngpt-4o-mini-ddg\ngpt-4o-2024-05-13\nmicrosoft/Phi-3.5-mini-instruct\nQwen/Qwen2.5-Coder-32B-Instruct\nQwen/QwQ-32B-Preview
\n\n✅️ We have 150+ models!\n🛡 https://t.me/ksenonapi_models", "image_models": "🌐 Image models:\n\n
flux-pro-mg\nflux-dev\nsd3-ultra\npixart-alpha
", "no_args": "⚠️ No arguments provided!", "update_available": "⚠️ KsenonGPT update available!\n\n🔼 New version: {}\n🔽 Current version: {}\n\n🌐 Changelog:\n🔔 {}\n\n✔️ Command to update:\n.dlmod https://raw.githubusercontent.com/TheKsenon/MyHikkaModules/refs/heads/main/ksenongpt.py", "latest_version": "🥳 You have the latest version of KsenonGPT!\n\n⚠️Developers are making updates and fixes almost every day, check frequently!", "select_model": "🤖 Select AI model:\n\n🔑 You can also specify a model directly by using .setmodel model_name", "model_set": "🎯 Model has been set to: {}", "invalid_model": "❌ Invalid model specified!", "need_set_model": "🔥 Please set the model using .setmodel command!" } strings_ru = { "name": "KsenonGPT", "no_api_key": "⚠️ Вы не настроили API ключ!\n\n🌐 Ключ очень легко достать, он бесплатный.\n\n🔓 Бот: @ksenonapi_gettoken_bot", "generating_text": "💬 Отвечаю на ваше сообщение...", "text_generated": "💬 Запрос: {}\n\n💬 {}", "generating_image": "🖼 Генерирую изображение...\n\n🤖 Модель: {}\n🔗 Запрос: {}", "image_generated": "🖼 Изображение сгенерировано!\n\n🤖 Модель: {}\n🔗 Запрос: {}\n\n📥 Ссылка: {}", "error_blocked": "🔒 Вы были заблокированы!\n\n🗑Запрещено генерировать NSFW | политика и т.д.", "error_occurred": "⚠️ Произошла ошибка!\n\n💻 Модель: {}\n📶 Статус сервера, код: {}\n➡️ Ошибка: {}", "text_models": "🌐 Текстовые модели:\n\n
o1-preview\ngpt-4o\nclaude-3-5-sonnet\nsearchgpt (GPT + Internet)\nblackboxai-pro\nclaude-3-5-sonnet-20240620\nclaude-3-haiku-ddg\ngemini-1.5-pro-latest\nllama-3.1-405b\ngpt-3.5-turbo-202201\ngpt-4o-mini-ddg\ngpt-4o-2024-05-13\nmicrosoft/Phi-3.5-mini-instruct\nQwen/Qwen2.5-Coder-32B-Instruct\nQwen/QwQ-32B-Preview
\n\n✅️ У нас 150+ моделей!\n🛡 https://t.me/ksenonapi_models", "image_models": "🌐 Модели для изображений:\n\n
flux-pro-mg\nflux-dev\nsd3-ultra\npixart-alpha
", "no_args": "⚠️ Не указаны аргументы!", "update_available": "⚠️ Доступно обновление KsenonGPT!\n\n🔼 Новая версия: {}\n🔽 Текущая версия: {}\n\n🌐 Список изменений:\n🔔 {}\n\n✔️ Команда для обновления:\n.dlmod https://raw.githubusercontent.com/TheKsenon/MyHikkaModules/refs/heads/main/ksenongpt.py", "latest_version": "🥳 У вас последняя версия KsenonGPT!\n\n⚠️Разработчики делают обновления и исправления почти каждый день, проверяйте чаще!", "select_model": "🤖 Выберите ИИ модель:\n\n🔑 Также вы можете указать конкретную модель, напишите .setmodel название_модели", "model_set": "🎯 Модель установлена: {}", "invalid_model": "❌ Указана неверная модель!", "need_set_model": "🔥 Поставьте модель в .setmodel!" } def __init__(self): self.config = loader.ModuleConfig( loader.ConfigValue( "api_key", "", "API key from @ksenonapi_gettoken_bot", validator=loader.validators.Hidden(), ), loader.ConfigValue( "default_model", "", "Default AI model to use", ) ) def _create_model_buttons(self): buttons = [] models = [ ("DeepSeek R1", "deepseek-r1"), ("GPT-4o", "gpt-4o"), ("Claude 3.5 Sonnet", "claude-3-5-sonnet"), ("SearchGPT", "searchgpt"), ("P1", "p1"), ("Gemini 2.0 Flash", "gemini-flash-2.0") ] row = [] for i, (name, model_id) in enumerate(models): row.append({"text": name, "callback": self._set_model, "args": (model_id,)}) if len(row) == 2: buttons.append(row) row = [] if row: buttons.append(row) return buttons async def setmodelcmd(self, message): """Set default AI model for text generation""" args = utils.get_args_raw(message) if args: self.config["default_model"] = args await utils.answer(message, self.strings["model_set"].format(args)) return await self.inline.form( text=self.strings["select_model"], message=message, reply_markup=self._create_model_buttons()) async def _set_model(self, call, model): self.config["default_model"] = model await call.edit( self.strings["model_set"].format(model), reply_markup=None) async def gentextcmd(self, message): """Generate text - .gentext """ if not self.config["api_key"]: await utils.answer(message, self.strings["no_api_key"]) return if not self.config["default_model"]: await utils.answer(message, self.strings["need_set_model"]) return args = utils.get_args_raw(message) if not args: await utils.answer(message, self.strings["no_args"]) return prompt = args model = self.config["default_model"] msg = await utils.answer(message, self.strings["generating_text"]) headers = { "Authorization": self.config["api_key"], "Content-Type": "application/json" } data = { "model": model, "prompt": prompt } async with aiohttp.ClientSession() as session: async with session.post( "http://aeza.theksenon.pro/v1/api/text/generate", headers=headers, json=data ) as response: result = await response.json() if response.status != 200: await utils.answer( msg, self.strings["error_occurred"].format( model, response.status, result.get("error", "Unknown error") ) ) return if "error" in result: if result["error"] == "Your token has been blocked": await utils.answer(msg, self.strings["error_blocked"]) return await utils.answer( msg, self.strings["error_occurred"].format( model, "N/A", result["error"] ) ) return await utils.answer( msg, self.strings["text_generated"].format( prompt, result["response"] ) ) async def genimgcmd(self, message): """Generate image - .genimg """ if not self.config["api_key"]: await utils.answer(message, self.strings["no_api_key"]) return args = utils.get_args_raw(message) if not args: await utils.answer(message, self.strings["no_args"]) return try: prompt, model = args.rsplit(maxsplit=1) except ValueError: prompt = args model = "flux-pro-mg" msg = await utils.answer( message, self.strings["generating_image"].format(model, prompt) ) headers = { "Authorization": self.config["api_key"], "Content-Type": "application/json" } data = { "model": model, "prompt": prompt } async with aiohttp.ClientSession() as session: async with session.post( "http://aeza.theksenon.pro/v1/api/image/generate", headers=headers, json=data ) as response: result = await response.json() if response.status != 200: await utils.answer( msg, self.strings["error_occurred"].format( model, response.status, result.get("error", "Unknown error") ) ) return if "error" in result: if result["error"] == "Your token has been blocked": await utils.answer(msg, self.strings["error_blocked"]) return await utils.answer( msg, self.strings["error_occurred"].format( model, "N/A", result["error"] ) ) return image_url = result["url"] async with session.get(image_url) as response: if response.status != 200: await utils.answer( msg, self.strings["error_occurred"].format( model, response.status, "Failed to download image" ) ) return image_data = io.BytesIO(await response.read()) image_data.name = "image.png" await self._client.send_file( message.peer_id, image_data, caption=self.strings["image_generated"].format( model, prompt, image_url ), reply_to=message.reply_to_msg_id ) if message.out: await message.delete() async def txtmodelscmd(self, message): """List of text models""" await utils.answer(message, self.strings["text_models"]) async def imgmodelscmd(self, message): """List of image models""" await utils.answer(message, self.strings["image_models"]) async def kupdatecmd(self, message): """Check for updates""" async with aiohttp.ClientSession() as session: async with session.get("https://raw.githubusercontent.com/TheKsenon/MyHikkaModules/refs/heads/main/ksenongpt.py") as response: if response.status != 200: return content = await response.text() try: version_line = [line for line in content.split("\n") if "__version__" in line][0] latest_version = tuple(map(int, version_line.split("(")[1].split(")")[0].split(","))) if latest_version > version: changelog = "New version available!" await utils.answer( message, self.strings["update_available"].format( ".".join(map(str, latest_version)), ".".join(map(str, version)), changelog ) ) else: await utils.answer(message, self.strings["latest_version"]) except: logger.error("Failed to parse version from GitHub")