Я создал тг-бота, задействующего функционал моделей от ollama, а так же hugging face. И не могу добавить ему адекватную возможность генерации изображений по запросам. Сейчас он может отвечать на вопросы, генерировать код и считывать информацию с изображений. Я пытался сам, но бот выдает ошибку: ⚠️ HuggingFace не смог сгенерировать изображение.
Причина:
Not Found
объясните все как можно проще т.к. я в программировании почти не смыслю. так же у меня ограничение по срокам, примерно неделя.
# ================= UTF-8 FIX FOR WINDOWS =================
import os
import sys
os.environ["PYTHONUTF8"] = "1"
sys.stdout.reconfigure(encoding="utf-8")
# ========================================================
import re
import base64
import requests
from telegram import Update
from telegram.ext import (
ApplicationBuilder,
CommandHandler,
MessageHandler,
ContextTypes,
filters,
)
# ================= НАСТРОЙКИ =================
TELEGRAM_BOT_TOKEN = "7076531027:AAEhLmNxcG4rVmJNSf8otuk9JoqwwYZP0Ps"
HF_TOKEN = "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"
OLLAMA_CHAT_URL = "http://localhost:11434/api/chat"
OLLAMA_GENERATE_URL = "http://localhost:11434/api/generate"
HF_IMAGE_MODEL_URL = (
"https://router.huggingface.co/hf-inference/models/"
"stabilityai/sdxl-turbo"
)
HF_HEADERS = {
"Authorization": f"Bearer {HF_TOKEN}"
}
TEXT_MODEL = "qwen2.5-coder:7b"
VISION_MODEL = "llava:latest"
# ========================================================
def split_text_safe(text: str, max_len: int = 4000):
if "```" in text:
return [text]
parts, current = [], ""
for line in text.split("\n"):
if len(current) + len(line) > max_len:
parts.append(current)
current = line
else:
current += ("\n" if current else "") + line
if current:
parts.append(current)
return parts
def is_code_request(text: str) -> bool:
keywords = [
"код", "напиши", "пример", "скрипт",
"python", "js", "javascript", "c++",
"функция", "класс", "бот", "api"
]
return any(k in text.lower() for k in keywords)
def ask_text_ai(prompt: str, is_code: bool = False) -> str:
system_prompt = (
"Ты русскоязычный ИИ-ассистент.\n"
"Отвечай СТРОГО на русском языке.\n"
)
if is_code:
system_prompt += (
"Ты опытный программист.\n"
"Пиши ТОЛЬКО рабочий код.\n"
"НЕ выдумывай несуществующие библиотеки и API.\n"
"Если информации недостаточно — задай уточняющий вопрос.\n"
"Перед кодом КРАТКО опиши логику.\n"
"Код оформляй ТОЛЬКО в ```.\n"
)
else:
system_prompt += (
"Отвечай кратко и по делу.\n"
"Не используй код, если его не просят.\n"
)
payload = {
"model": TEXT_MODEL,
"stream": False,
"messages": [
{"role": "system", "content": system_prompt},
{"role": "user", "content": prompt}
]
}
r = requests.post(OLLAMA_CHAT_URL, json=payload, timeout=120)
return r.json()["message"]["content"]
def generate_image(prompt: str) -> tuple[bytes | None, str | None]:
payload = {
"inputs": prompt,
"options": {
"wait_for_model": True
}
}
try:
r = requests.post(
HF_IMAGE_MODEL_URL,
headers=HF_HEADERS,
json=payload,
timeout=300
)
content_type = r.headers.get("content-type", "")
# ✅ УСПЕХ — ПРИШЛА КАРТИНКА
if r.status_code == 200 and "image" in content_type:
return r.content, None
# ⚠️ HF вернул JSON (ошибка / статус)
try:
data = r.json()
error = data.get("error", str(data))
except Exception:
error = r.text
return None, error
except Exception as e:
return None, str(e)
async def handle_image_generation(update: Update, context: ContextTypes.DEFAULT_TYPE):
chat_id = update.effective_chat.id
prompt = " ".join(context.args)
if not prompt:
await update.message.reply_text(
"❌ Использование:\n/img описание изображения"
)
return
await context.bot.send_chat_action(chat_id, "upload_photo")
image_bytes, error = generate_image(prompt)
if not image_bytes:
await update.message.reply_text(
"⚠️ HuggingFace не смог сгенерировать изображение.\n\n"
f"Причина:\n{error}"
)
return
await context.bot.send_photo(
chat_id,
photo=image_bytes,
caption=f" Запрос:\n{prompt}"
)
def ask_vision_ai(prompt: str, image_bytes: bytes) -> str:
image_base64 = base64.b64encode(image_bytes).decode("utf-8")
payload = {
"model": VISION_MODEL,
"prompt": (
"Опиши изображение.\n"
"Если есть текст — перепиши его.\n\n"
f"{prompt}"
),
"images": [image_base64],
"stream": False
}
r = requests.post(OLLAMA_GENERATE_URL, json=payload, timeout=180)
data = r.json()
if "response" not in data:
return f"⚠️ Неожиданный ответ Ollama:\n{data}"
return data["response"]
def normalize_russian(text: str) -> str:
payload = {
"model": TEXT_MODEL,
"stream": False,
"messages": [
{
"role": "system",
"content": (
"Ты редактор русского текста.\n"
"Исправь стиль, грамматику и логику.\n"
"Убери английские слова.\n"
"Отвечай только на русском."
)
},
{
"role": "user",
"content": text
}
]
}
try:
r = requests.post(OLLAMA_CHAT_URL, json=payload, timeout=60)
return r.json()["message"]["content"]
except Exception:
return text
# ================= HANDLERS =================
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.message.reply_text(
" Lion.AI запущен, я умею:\n\n"
"• Отвечать на вопросы\n"
"• Писать код\n"
"• Считывать информацию с изображений\n"
"• Генерировать картинки с помощью команды /img"
)
async def handle_text(update: Update, context: ContextTypes.DEFAULT_TYPE):
chat_id = update.effective_chat.id
await context.bot.send_chat_action(chat_id, "typing")
user_text = update.message.text
code_request = is_code_request(user_text)
answer = ask_text_ai(user_text, is_code=code_request)
for part in split_text_safe(answer):
await context.bot.send_message(
chat_id,
part,
parse_mode="Markdown"
)
async def handle_photo(update: Update, context: ContextTypes.DEFAULT_TYPE):
chat_id = update.effective_chat.id
await context.bot.send_chat_action(chat_id, "typing")
photo = update.message.photo[-1]
file = await context.bot.get_file(photo.file_id)
image_bytes = await file.download_as_bytearray()
caption = update.message.caption or "Опиши изображение"
answer = ask_vision_ai(caption, image_bytes)
answer = normalize_russian(answer)
for part in split_text_safe(answer):
await context.bot.send_message(
chat_id,
part,
parse_mode="Markdown"
)
# ================= MAIN =================
def main():
app = ApplicationBuilder().token(TELEGRAM_BOT_TOKEN).build()
app.add_handler(CommandHandler("start", start))
app.add_handler(CommandHandler("img", handle_image_generation))
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_text))
app.add_handler(MessageHandler(filters.PHOTO, handle_photo))
print("✅ Бот запущен")
app.run_polling()
if __name__ == "__main__":
main()