feat: update to June 2026 models (Claude Sonnet 4.6, Gemini 3.5 Flash), add glossary button, and implement cost factor quota & vision fallback
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m4s

This commit is contained in:
2026-06-14 11:05:53 +02:00
parent 5fd087979b
commit 136d40c7d8
10 changed files with 145 additions and 74 deletions

View File

@@ -501,19 +501,21 @@ def check_usage_limits(user: User) -> Dict[str, Any]:
}
def record_usage(user_id: str, pages_count: int, use_credits: bool = False) -> bool:
"""Record document translation usage"""
def record_usage(
user_id: str, pages_count: int, use_credits: bool = False, cost_factor: int = 1
) -> bool:
"""Record document translation usage with optional cost factor depending on AI model"""
user = get_user_by_id(user_id)
if not user:
return False
updates = {
"docs_translated_this_month": user.docs_translated_this_month + 1,
"pages_translated_this_month": user.pages_translated_this_month + pages_count,
"docs_translated_this_month": user.docs_translated_this_month + cost_factor,
"pages_translated_this_month": user.pages_translated_this_month + (pages_count * cost_factor),
}
if use_credits:
updates["extra_credits"] = max(0, user.extra_credits - pages_count)
updates["extra_credits"] = max(0, user.extra_credits - (pages_count * cost_factor))
result = update_user(user_id, updates)
return result is not None

View File

@@ -903,11 +903,12 @@ RULES:
else "image/png"
)
# Determine a vision model. If the current model doesn't support vision,
# use a fast vision fallback model like google/gemini-2.0-flash-001
vision_model = self.model
if "deepseek" in vision_model:
vision_model = "google/gemini-2.0-flash-001"
vision_supported_keywords = ["gpt-4", "claude", "gemini", "fable", "pixtral", "llama-3.2", "grok-2"]
has_vision = any(kw in vision_model.lower() for kw in vision_supported_keywords)
if not has_vision:
vision_model = "google/gemini-3.5-flash"
session = self._get_session()
payload = {
@@ -1083,7 +1084,10 @@ ADDITIONAL CONTEXT AND INSTRUCTIONS:
try:
import openai
client = openai.OpenAI(api_key=self.api_key)
client_kwargs = {"api_key": self.api_key}
if self.base_url:
client_kwargs["base_url"] = self.base_url
client = openai.OpenAI(**client_kwargs)
# Read and encode image
with open(image_path, "rb") as img_file:
@@ -1097,8 +1101,20 @@ ADDITIONAL CONTEXT AND INSTRUCTIONS:
else "image/png"
)
# Determine a vision model. If the current model doesn't support vision,
# use a fast vision fallback model
vision_model = self.model
vision_supported_keywords = ["gpt-4", "claude", "gemini", "fable", "pixtral", "llama-3.2", "grok-2"]
has_vision = any(kw in vision_model.lower() for kw in vision_supported_keywords)
if not has_vision:
if self.base_url and "openrouter.ai" in self.base_url:
vision_model = "google/gemini-3.5-flash"
else:
vision_model = "gpt-4o-mini"
response = client.chat.completions.create(
model=self.model, # gpt-4o and gpt-4o-mini support vision
model=vision_model,
messages=[
{
"role": "user",
@@ -1121,7 +1137,7 @@ ADDITIONAL CONTEXT AND INSTRUCTIONS:
return response.choices[0].message.content.strip()
except Exception as e:
logger.warning("openai_vision_error", error_type=type(e).__name__)
logger.warning("openai_vision_error", error_type=type(e).__name__, error=str(e))
return ""