SilverElixir commited on
Commit
ca87bda
·
verified ·
1 Parent(s): e7f820c

Upload bot.py

Browse files
Files changed (1) hide show
  1. bot.py +62 -27
bot.py CHANGED
@@ -528,7 +528,11 @@ GEMINI_MODELS: dict[str, dict[str, Any]] = {
528
  "gemma-4-31b-it": {
529
  "name": "Gemma 4 31B", "badge": "Открытая модель",
530
  "desc": "Флагманская открытая модель Google на 31 млрд параметров — топ-3 среди открытых моделей мира по качеству рассуждений, кода и работы с изображениями.", "no_system": True, "no_search": True, "stream": True,
531
- }
 
 
 
 
532
  }
533
  DEFAULT_GEMINI_MODEL = "gemini-3.5-flash"
534
 
@@ -849,35 +853,38 @@ HF_IMAGE_MODEL_PAGE_SIZE = 8
849
  HF_IMAGE_MODEL_CALLBACKS: dict[str, str] = {}
850
 
851
  HF_IMAGE_MODELS: dict[str, dict[str, Any]] = {
852
- "black-forest-labs/FLUX.1-dev": {
853
- "name": "FLUX.1 Dev", "badge": "⭐ Лучшая",
854
- "desc": "Флагманская модель Black Forest Labs. Фотореализм, точное следование промпту, детализация — эталон качества для FLUX-линейки."
855
  },
856
- "black-forest-labs/FLUX.1-Kontext-dev": {
857
- "name": "FLUX.1 Kontext", "badge": "Редактирование",
858
- "desc": "Специализирована на редактировании изображений и следовании контексту. Позволяет точечно менять стиль, объекты и фон по текстовой инструкции."
859
  },
860
- "stabilityai/stable-diffusion-3.5-large": {
861
- "name": "SD 3.5 Large", "badge": "Качество",
862
- "desc": "Крупная модель Stability AI третьего поколения. Высокая детализация, понимание сложных промптов, улучшенная анатомия и текст внутри изображений."
863
  },
864
- "black-forest-labs/FLUX.1-schnell": {
865
- "name": "FLUX.1 Schnell", "badge": "Быстрая",
866
- "desc": "Дистиллированная версия FLUX.1 Dev для скоростной генерации. 1–4 шага вместо 20–50 — результат за секунды при хорошем качестве."
867
  },
868
- "stabilityai/stable-diffusion-xl-base-1.0": {
869
- "name": "SDXL Base 1.0", "badge": "Классика",
870
- "desc": "Проверенная базовая модель Stable Diffusion XL. Широкое сообщество, тысячи LoRA и стилей, стабильный предсказуемый результат."
871
  },
872
- "stabilityai/sdxl-turbo": {
873
- "name": "SDXL Turbo", "badge": "Сверхбыстрая",
874
- "desc": "Adversarial дистилляция SDXL генерация за 1–4 шага. Идеально для быстрых набросков, итераций и проверки идей."
875
  },
876
  }
877
 
878
 
879
  def _hf_image_headers() -> dict[str, str]:
880
- headers = {"Accept": "application/json, image/*, application/octet-stream", "User-Agent": "IlvorBot/8.2"}
 
 
 
881
  if HF_TOKEN:
882
  headers["Authorization"] = f"Bearer {HF_TOKEN}"
883
  return headers
@@ -894,9 +901,7 @@ async def _hf_fetch_model_catalog(force: bool = False) -> list[dict[str, Any]]:
894
 
895
  def _imgmodel_button_text(model: dict[str, Any], current: str) -> str:
896
  prefix = "• " if model["id"] == current else ""
897
- badge = model.get("badge")
898
- suffix = f" [{badge}]" if badge else ""
899
- return f"{prefix}{model['name']}{suffix}"
900
 
901
 
902
  def _imgmodel_keyboard(current: str, page: int = 0) -> InlineKeyboardMarkup:
@@ -925,7 +930,31 @@ def _imgmodel_keyboard(current: str, page: int = 0) -> InlineKeyboardMarkup:
925
  return InlineKeyboardMarkup(inline_keyboard=rows)
926
 
927
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
928
  async def _hf_text_to_image(model_id: str, prompt: str) -> bytes:
 
 
 
 
 
 
929
  session = await _get_http_session()
930
  url = f"{HF_IMAGE_API_BASE}/models/{urllib.parse.quote(model_id, safe='')}"
931
  payload = {
@@ -1889,6 +1918,7 @@ async def ask_gemini(chat_id: int, user_text: str, media: list[tuple[bytes, str]
1889
  "gemini-2.5-flash",
1890
  "gemini-2.5-flash-lite",
1891
  "gemma-4-31b-it",
 
1892
  ]
1893
 
1894
  loop_guard = 0
@@ -2215,13 +2245,18 @@ def gemini_kb(current: str) -> InlineKeyboardMarkup:
2215
  return InlineKeyboardMarkup(inline_keyboard=grid)
2216
 
2217
  def _get_gemini_model_limit_info(model_id: str) -> str:
 
 
 
 
2218
  limits_map = {
2219
- "gemini-3.5-flash": 1500,
2220
- "gemini-3-flash-preview": 1500,
2221
  "gemini-3.1-flash-lite": 500,
2222
- "gemini-2.5-flash": 250,
2223
- "gemini-2.5-flash-lite": 1000,
2224
  "gemma-4-31b-it": 1500,
 
2225
  }
2226
  limit = limits_map.get(model_id, 20)
2227
  e = _quota_entry(None, "gemini", model_id)
 
528
  "gemma-4-31b-it": {
529
  "name": "Gemma 4 31B", "badge": "Открытая модель",
530
  "desc": "Флагманская открытая модель Google на 31 млрд параметров — топ-3 среди открытых моделей мира по качеству рассуждений, кода и работы с изображениями.", "no_system": True, "no_search": True, "stream": True,
531
+ },
532
+ "gemma-4-26b-a4b-it": {
533
+ "name": "Gemma 4 26B", "badge": "Открытая модель",
534
+ "desc": "Компактная открытая модель Google на 26 млрд параметров с поддержкой расширенного мышления (thinking). Хороший баланс качества и скорости среди Gemma-семейства.", "no_system": True, "stream": True,
535
+ },
536
  }
537
  DEFAULT_GEMINI_MODEL = "gemini-3.5-flash"
538
 
 
853
  HF_IMAGE_MODEL_CALLBACKS: dict[str, str] = {}
854
 
855
  HF_IMAGE_MODELS: dict[str, dict[str, Any]] = {
856
+ "pollinations:flux": {
857
+ "name": "FLUX Pro",
858
+ "desc": "Высококачественный FLUX через Pollinations.ai. Фотореализм, точное следование промпту, богатая детализация.",
859
  },
860
+ "pollinations:flux-realism": {
861
+ "name": "FLUX Realism",
862
+ "desc": "FLUX с акцентом на гиперреализм детализированные текстуры, естественное освещение, кинематографичность.",
863
  },
864
+ "pollinations:flux-anime": {
865
+ "name": "FLUX Anime",
866
+ "desc": "FLUX для аниме и иллюстраций — характерные пропорции, яркие цвета, стилизация под японскую графику.",
867
  },
868
+ "pollinations:turbo": {
869
+ "name": "Turbo",
870
+ "desc": "Быстрая дистиллированная модель. Результат за несколько секунд для черновиков и быстрых итераций.",
871
  },
872
+ "pollinations:dreamshaper": {
873
+ "name": "DreamShaper",
874
+ "desc": "Художественная модель для фэнтези, концепт-арта и стилизованных иллюстраций.",
875
  },
876
+ "black-forest-labs/FLUX.1-schnell": {
877
+ "name": "FLUX.1 Schnell (HF)",
878
+ "desc": "Оригинальная FLUX.1 Schnell от Black Forest Labs через Hugging Face Inference API. Быстрая, Apache 2.0.",
879
  },
880
  }
881
 
882
 
883
  def _hf_image_headers() -> dict[str, str]:
884
+ headers = {
885
+ "Accept": "image/png, image/jpeg, image/webp, application/json",
886
+ "User-Agent": "IlvorBot/8.2"
887
+ }
888
  if HF_TOKEN:
889
  headers["Authorization"] = f"Bearer {HF_TOKEN}"
890
  return headers
 
901
 
902
  def _imgmodel_button_text(model: dict[str, Any], current: str) -> str:
903
  prefix = "• " if model["id"] == current else ""
904
+ return f"{prefix}{model['name']}"
 
 
905
 
906
 
907
  def _imgmodel_keyboard(current: str, page: int = 0) -> InlineKeyboardMarkup:
 
930
  return InlineKeyboardMarkup(inline_keyboard=rows)
931
 
932
 
933
+ async def _pollinations_generate(model_name: str, prompt: str) -> bytes:
934
+ """Бесплатная генерация через Pollinations.ai — не требует авторизации."""
935
+ session = await _get_http_session()
936
+ encoded = urllib.parse.quote(prompt[:600], safe="")
937
+ url = (
938
+ f"https://image.pollinations.ai/prompt/{encoded}"
939
+ f"?width=1024&height=1024&model={model_name}&nologo=true&enhance=false"
940
+ )
941
+ async with session.get(url, timeout=aiohttp.ClientTimeout(total=90)) as resp:
942
+ if resp.status == 200:
943
+ ctype = (resp.headers.get("Content-Type") or "").lower()
944
+ body = await resp.read()
945
+ if body and (ctype.startswith("image/") or body[:4] in (b"\x89PNG", b"\xff\xd8\xff", b"RIFF", b"GIF8")):
946
+ return body
947
+ raise RuntimeError(f"Pollinations вернул не-изображение: {ctype}")
948
+ raise RuntimeError(f"Pollinations.ai HTTP {resp.status}")
949
+
950
+
951
  async def _hf_text_to_image(model_id: str, prompt: str) -> bytes:
952
+ # Pollinations.ai — бесплатный провайдер без авторизации
953
+ if model_id.startswith("pollinations:"):
954
+ poll_model = model_id.split(":", 1)[1]
955
+ return await _pollinations_generate(poll_model, prompt)
956
+
957
+ # HF Inference API (router.huggingface.co/hf-inference)
958
  session = await _get_http_session()
959
  url = f"{HF_IMAGE_API_BASE}/models/{urllib.parse.quote(model_id, safe='')}"
960
  payload = {
 
1918
  "gemini-2.5-flash",
1919
  "gemini-2.5-flash-lite",
1920
  "gemma-4-31b-it",
1921
+ "gemma-4-26b-a4b-it",
1922
  ]
1923
 
1924
  loop_guard = 0
 
2245
  return InlineKeyboardMarkup(inline_keyboard=grid)
2246
 
2247
  def _get_gemini_model_limit_info(model_id: str) -> str:
2248
+ # Реальные лимиты по официальному дашборду AI Studio (June 2026).
2249
+ # Строка вида "32 / 20" означает: пик использования / лимит.
2250
+ # 3.x Flash/Preview = 20-25 RPD; 3.1 Flash-Lite = 500 RPD;
2251
+ # 2.5 Flash = 20 RPD; 2.5 Flash-Lite = 20 RPD; Gemma 4 = 1500 RPD.
2252
  limits_map = {
2253
+ "gemini-3.5-flash": 20,
2254
+ "gemini-3-flash-preview": 25,
2255
  "gemini-3.1-flash-lite": 500,
2256
+ "gemini-2.5-flash": 20,
2257
+ "gemini-2.5-flash-lite": 20,
2258
  "gemma-4-31b-it": 1500,
2259
+ "gemma-4-26b-a4b-it": 1500,
2260
  }
2261
  limit = limits_map.get(model_id, 20)
2262
  e = _quota_entry(None, "gemini", model_id)