added proxy

This commit is contained in:
2026-07-07 10:20:06 +03:00
parent 7f3599a859
commit d793ea90ba
2 changed files with 92 additions and 10 deletions
+65
View File
@@ -0,0 +1,65 @@
# ── LLM (OpenRouter / любой совместимый провайдер) ────────────
# Базовый URL и ключ:
# - по умолчанию: OpenRouter
# - можно переопределить под другой API, если он совместим по формату
LLM_BASE_URL=https://openrouter.ai/api/v1/chat/completions
LLM_API_KEY=sk-or-v1-...
# Для обратной совместимости с текущей конфигурацией:
ROUTER_KEY=${LLM_API_KEY}
# Авторизационный заголовок и префикс (опционально):
#LLM_AUTH_HEADER=Authorization
#LLM_AUTH_PREFIX=Bearer
# Прокси: HTTP или SOCKS5, например:
# socks5://user:pass@127.0.0.1:1080
# http://127.0.0.1:8080
# Любая из переменных может использоваться (берётся первая непустая):
#LLM_PROXY=
#LLM_SOCKS5=
#LLM_SOCKS5_PROXY=
# ── Model routing ─────────────────────────────────────────────
CHAT_MODEL=deepseek/deepseek-v4-flash
SYSTEM_MODEL=deepseek/deepseek-chat-v3
LLM_FALLBACK_MODEL=mistralai/mistral-nemo
RPG_PLOT_MODEL=deepseek/deepseek-chat-v3
RPG_NARRATOR_MODEL=deepseek/deepseek-chat-v3
RPG_FACTS_MODEL=deepseek/deepseek-chat-v3
SD_PROMPT_MODEL=deepseek/deepseek-chat-v3
FACTS_STORE_LIMIT=100
# ── Comfy / SD ────────────────────────────────────────────────
# Comfy на том же хосте, что и docker compose (Linux):
# вариант A — LAN-IP сервера (часто работает сразу)
SD_BASE_URL=http://192.168.1.109:8188
# вариант B — host.docker.internal (нужен extra_hosts в compose, уже добавлен)
# SD_BASE_URL=http://host.docker.internal:8188
# Comfy на другой машине в сети:
# SD_BASE_URL=http://84.50.156.15:8188
SD_COMFY_TOKEN=
SD_CHECKPOINT=
SD_UNET=anima-preview3-base.safetensors
SD_CLIP=qwen_3_06b_base.safetensors
SD_VAE=qwen_image_vae.safetensors
SD_STYLE_LORA=anima-preview-3-masterpieces-v5.safetensors
SD_STYLE_LORA_WEIGHT=0.7
SD_AUTO_GENERATE=true
SD_STEPS=30
SD_CFG=4
SD_SAMPLER=er_sde
SD_SCHEDULER=simple
SD_ANIMA_DUAL_COMPARE=false
# ── LibreTranslate ────────────────────────────────────────────
# Тот же хост: LAN-IP или host.docker.internal:5100
LIBRETRANSLATE_URL=http://192.168.1.109:5100
# Порт веб-UI и API (по умолчанию 8201)
APP_PORT=8201
# DB_PATH и IMAGES_DIR заданы в docker-compose.yml — в .env не нужны
+27 -10
View File
@@ -8,16 +8,33 @@ load_dotenv()
logger = logging.getLogger(__name__)
OPENROUTER_KEY = os.getenv("ROUTER_KEY")
OPENROUTER_URL = "https://openrouter.ai/api/v1/chat/completions"
# ── Provider / transport configuration ─────────────────────────────
# По умолчанию работаем через OpenRouter, но базовый URL и ключ
# можно переопределить для любого совместимого провайдера.
LLM_BASE_URL = (
os.getenv("LLM_BASE_URL")
or "https://openrouter.ai/api/v1/chat/completions"
)
LLM_API_KEY = os.getenv("LLM_API_KEY") or os.getenv("ROUTER_KEY")
LLM_AUTH_HEADER = os.getenv("LLM_AUTH_HEADER", "Authorization")
LLM_AUTH_PREFIX = os.getenv("LLM_AUTH_PREFIX", "Bearer ")
# SOCKS5 / HTTP‑прокси (например: socks5://user:pass@host:1080)
LLM_PROXY_URL = (
os.getenv("LLM_PROXY")
or os.getenv("LLM_SOCKS5")
or os.getenv("LLM_SOCKS5_PROXY")
)
PROXIES = {"all": LLM_PROXY_URL} if LLM_PROXY_URL else None
# ── Модели ─────────────────────────────────────────────────────────
CHAT_MODEL = os.getenv("CHAT_MODEL", "mistralai/mistral-nemo")
SYSTEM_MODEL = os.getenv("SYSTEM_MODEL", "google/gemini-2.5-flash")
# Softer model when primary returns content_filter / empty / API errors (default: CHAT_MODEL).
LLM_FALLBACK_MODEL = (os.getenv("LLM_FALLBACK_MODEL") or "").strip() or CHAT_MODEL
HEADERS = {
"Authorization": f"Bearer {OPENROUTER_KEY}",
LLM_AUTH_HEADER: f"{LLM_AUTH_PREFIX}{LLM_API_KEY}" if LLM_API_KEY else "",
"Content-Type": "application/json",
"HTTP-Referer": "http://localhost:8000",
}
@@ -86,12 +103,12 @@ def _clean(messages: list) -> list:
async def _post_once(model: str, messages: list, extra: dict | None = None) -> str:
if not OPENROUTER_KEY:
raise LLMError("ROUTER_KEY is not set in environment")
if not LLM_API_KEY:
raise LLMError("LLM_API_KEY / ROUTER_KEY is not set in environment")
payload = {"model": model, "messages": _clean(messages), **(extra or {})}
async with httpx.AsyncClient(timeout=90) as client:
r = await client.post(OPENROUTER_URL, headers=HEADERS, json=payload)
async with httpx.AsyncClient(timeout=90, proxies=PROXIES) as client:
r = await client.post(LLM_BASE_URL, headers=HEADERS, json=payload)
try:
data = r.json()
except Exception as e:
@@ -108,7 +125,7 @@ async def _post_once(model: str, messages: list, extra: dict | None = None) -> s
return _parse_completion_body(data)
except LLMError:
logger.warning(
"OpenRouter completion failed model=%s status=%s body=%.500s",
"LLM completion failed model=%s status=%s body=%.500s",
model,
r.status_code,
data,
@@ -157,9 +174,9 @@ async def stream_message(messages: list):
}
timeout = httpx.Timeout(connect=10, read=120, write=10, pool=5)
chunk_count = 0
async with httpx.AsyncClient(timeout=timeout) as client:
async with httpx.AsyncClient(timeout=timeout, proxies=PROXIES) as client:
try:
async with client.stream("POST", OPENROUTER_URL, headers=HEADERS, json=payload) as response:
async with client.stream("POST", LLM_BASE_URL, headers=HEADERS, json=payload) as response:
response.raise_for_status()
buf = ""
async for raw in response.aiter_bytes():