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
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m4s
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 ""
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user