fixed proxy

This commit is contained in:
2026-09-08 10:53:06 +03:00
parent c94a6e2329
commit 181f84d372
2 changed files with 137 additions and 71 deletions
+96 -44
View File
@@ -37,6 +37,101 @@ TABLE_TYPE_LABELS = {
"simple_list": "Бланк заказа",
}
def _openrouter_proxy_url() -> str | None:
settings = get_settings()
proxy = (settings.openrouter_proxy or "").strip() or None
if proxy and "://" not in proxy:
proxy = f"socks5://{proxy}"
return proxy
def openrouter_headers() -> dict[str, str]:
settings = get_settings()
return {
"Authorization": f"Bearer {settings.openrouter_api_key}",
"Content-Type": "application/json",
"HTTP-Referer": "https://gostgenerator.local",
"X-Title": "GostGenerator Web",
}
def openrouter_chat_url() -> str:
return get_settings().openrouter_base_url.rstrip("/") + "/chat/completions"
async def openrouter_chat(
messages: list[dict[str, str]],
*,
temperature: float = 0.2,
max_tokens: int = 2000,
) -> str:
"""Shared OpenRouter chat/completions call (same key, proxy, model as ESKD chat)."""
settings = get_settings()
if not settings.openrouter_api_key:
raise RuntimeError("OpenRouter API key не настроен (OPENROUTER_API_KEY).")
payload = {
"model": settings.openrouter_model,
"messages": messages,
"temperature": temperature,
"max_tokens": max_tokens,
}
client_kwargs: dict[str, Any] = {"timeout": 120.0}
proxy = _openrouter_proxy_url()
if proxy:
client_kwargs["proxy"] = proxy
async with httpx.AsyncClient(**client_kwargs) as client:
resp = await client.post(
openrouter_chat_url(),
headers=openrouter_headers(),
json=payload,
)
if resp.status_code >= 400:
detail = resp.text[:500]
raise RuntimeError(f"OpenRouter HTTP {resp.status_code}: {detail}")
data = resp.json()
return data["choices"][0]["message"]["content"] or ""
def openrouter_chat_sync(
messages: list[dict[str, str]],
*,
temperature: float = 0.2,
max_tokens: int = 2000,
) -> str:
"""Sync variant for non-async endpoints (same transport as ESKD chat)."""
settings = get_settings()
if not settings.openrouter_api_key:
raise RuntimeError("OpenRouter API key не настроен (OPENROUTER_API_KEY).")
payload = {
"model": settings.openrouter_model,
"messages": messages,
"temperature": temperature,
"max_tokens": max_tokens,
}
client_kwargs: dict[str, Any] = {"timeout": 120.0}
proxy = _openrouter_proxy_url()
if proxy:
client_kwargs["proxy"] = proxy
with httpx.Client(**client_kwargs) as client:
resp = client.post(
openrouter_chat_url(),
headers=openrouter_headers(),
json=payload,
)
if resp.status_code >= 400:
detail = resp.text[:500]
raise RuntimeError(f"OpenRouter HTTP {resp.status_code}: {detail}")
data = resp.json()
return data["choices"][0]["message"]["content"] or ""
def estimate_tokens(text: str) -> int:
"""Rough token estimate (works for mixed RU/EN)."""
if not text:
@@ -159,36 +254,8 @@ async def chat_edit_table(
hist.append({"role": "user", "content": message})
messages = build_llm_messages(table_type, rows, hist)
context = build_context_usage(messages)
content = await openrouter_chat(messages, temperature=0.2, max_tokens=2000)
payload = {
"model": settings.openrouter_model,
"messages": messages,
"temperature": 0.2,
"max_tokens": 2000,
}
headers = {
"Authorization": f"Bearer {settings.openrouter_api_key}",
"Content-Type": "application/json",
"HTTP-Referer": "https://gostgenerator.local",
"X-Title": "GostGenerator Web",
}
url = settings.openrouter_base_url.rstrip("/") + "/chat/completions"
proxy = (settings.openrouter_proxy or "").strip() or None
if proxy and "://" not in proxy:
proxy = f"socks5://{proxy}"
client_kwargs: dict[str, Any] = {"timeout": 90.0}
if proxy:
client_kwargs["proxy"] = proxy
async with httpx.AsyncClient(**client_kwargs) as client:
resp = await client.post(url, headers=headers, json=payload)
resp.raise_for_status()
data = resp.json()
content = data["choices"][0]["message"]["content"]
parsed = _extract_json(content)
edits = parsed.get("edits") or []
norm_edits = []
@@ -204,22 +271,7 @@ async def chat_edit_table(
}
)
# include assistant reply in usage estimate
context = build_context_usage(messages + [{"role": "assistant", "content": content}])
usage = data.get("usage") or {}
if usage.get("prompt_tokens"):
prompt_t = int(usage["prompt_tokens"])
completion_t = int(usage.get("completion_tokens") or 0)
total_t = int(usage.get("total_tokens") or (prompt_t + completion_t))
limit = settings.llm_context_limit
context = {
"used": total_t,
"limit": limit,
"percent": min(100.0, round(100.0 * total_t / limit, 1)) if limit else 0.0,
"prompt_tokens": prompt_t,
"completion_tokens": completion_t,
}
return {"reply": parsed.get("reply") or "", "edits": norm_edits, "context": context}