| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- from __future__ import annotations
-
- import base64
- import logging
- import os
- import time as _time
-
- import cv2
- import requests
-
- from src.env import load_env
-
- logger = logging.getLogger(__name__)
-
- API_URL: str = "https://opencode.ai/zen/go/v1/messages"
- DEFAULT_MODEL: str = "qwen3.8-max"
- IMAGE_QUALITY: int = 90
-
- _ENV_LOADED: bool = False
-
-
- def _ensure_env() -> None:
- global _ENV_LOADED
- if _ENV_LOADED:
- return
- load_env()
- _ENV_LOADED = True
-
-
- def _api_key() -> str:
- _ensure_env()
- return os.environ.get("OPENCODE_API_KEY", "")
-
-
- def image_to_base64(image) -> str:
- _, buf = cv2.imencode(".jpg", image, [cv2.IMWRITE_JPEG_QUALITY, IMAGE_QUALITY])
- return base64.b64encode(buf).decode("utf-8")
-
-
- def call_qwen_vlm(
- image_b64: str,
- prompt: str,
- model: str = DEFAULT_MODEL,
- max_tokens: int = 300,
- ) -> str | None:
- """Отправляет изображение + prompt в Qwen3.8 Max API и возвращает текст ответа."""
- if not _api_key():
- logger.warning("OPENCODE_API_KEY не задан")
- return None
-
- messages = [{
- "role": "user",
- "content": [
- {"type": "image", "source": {"type": "base64", "media_type": "image/jpeg", "data": image_b64}},
- {"type": "text", "text": prompt},
- ],
- }]
-
- for attempt in (1, 2):
- try:
- r = requests.post(
- API_URL,
- headers={"x-api-key": _api_key(), "anthropic-version": "2023-06-01", "Content-Type": "application/json"},
- json={"model": model, "max_tokens": max_tokens, "messages": messages},
- timeout=120,
- )
- r.raise_for_status()
- data = r.json()
- for item in data.get("content", []):
- if item.get("type") == "text":
- return item.get("text", "").strip()
- return None
- except requests.HTTPError as e:
- if e.response is not None and e.response.status_code == 500 and attempt == 1:
- logger.info("Qwen API: HTTP 500, ожидание 5с и повтор...")
- _time.sleep(5)
- continue
- logger.warning("Qwen API: ошибка — %s", e)
- return None
- except (requests.RequestException, KeyError, IndexError) as e:
- logger.warning("Qwen API: ошибка — %s", e)
- return None
- return None
|