feat: unify multimodels translation providers, remove self-hosting (Ollama/LibreTranslate), and fix local SQLite configuration
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m21s

This commit is contained in:
2026-06-14 10:44:46 +02:00
parent feea02033b
commit 5fd087979b
21 changed files with 157 additions and 1942 deletions

View File

@@ -646,10 +646,8 @@ async def update_default_provider(
"google",
"deepl",
"openai",
"ollama",
"openrouter",
"zai",
"libre",
"classic",
"llm",
]
@@ -848,7 +846,7 @@ class SettingsConfig(BaseModel):
google_cloud: ProviderSettings = ProviderSettings() # Cloud Translation API v2 (clé API)
deepl: ProviderSettings = ProviderSettings()
openai: ProviderSettings = ProviderSettings()
ollama: ProviderSettings = ProviderSettings() # dev-only in UI
openrouter: ProviderSettings = ProviderSettings() # "Traduction IA Essentielle"
openrouter_premium: ProviderSettings = ProviderSettings() # "Traduction IA Premium"
deepseek: ProviderSettings = ProviderSettings()
@@ -924,7 +922,7 @@ async def get_settings(admin_id: str = Depends(require_admin)):
payload["deepseek"] = _merge_env(settings.deepseek, key_env="DEEPSEEK_API_KEY", model_env="DEEPSEEK_MODEL", default_model="deepseek-chat")
payload["minimax"] = _merge_env(settings.minimax, key_env="MINIMAX_API_KEY", model_env="MINIMAX_MODEL", default_model="abab6.5s-chat")
payload["zai"] = _merge_env(settings.zai, key_env="ZAI_API_KEY", model_env="ZAI_MODEL", url_env="ZAI_BASE_URL", default_model="grok-2-1212", default_url="https://api.x.ai/v1")
payload["ollama"] = _merge_env(settings.ollama, url_env="OLLAMA_BASE_URL", model_env="OLLAMA_MODEL", default_url="http://localhost:11434", default_model="llama3")
payload["google_cloud"] = _merge_env(settings.google_cloud, key_env="GOOGLE_CLOUD_API_KEY")
# SMTP: merge from env vars, but never expose password
@@ -958,7 +956,7 @@ async def get_settings(admin_id: str = Depends(require_admin)):
"deepseek": bool(os.getenv("DEEPSEEK_API_KEY", "").strip()),
"minimax": bool(os.getenv("MINIMAX_API_KEY", "").strip()),
"zai": bool(os.getenv("ZAI_API_KEY", "").strip()),
"ollama": bool(os.getenv("OLLAMA_BASE_URL", "").strip()),
"google_cloud": bool(os.getenv("GOOGLE_CLOUD_API_KEY", "").strip()),
"smtp": bool(os.getenv("SMTP_HOST", "").strip()),
}
@@ -1116,22 +1114,6 @@ async def test_provider(
content={"available": True, "models_count": len(models)},
)
elif provider == "ollama":
import requests as _requests
base_url = (provider_config.base_url or "").strip() or os.getenv("OLLAMA_BASE_URL", "http://localhost:11434")
resp = _requests.get(f"{base_url}/api/tags", timeout=5)
if resp.ok:
return JSONResponse(
status_code=200,
content={
"available": True,
"models": resp.json().get("models", []),
},
)
return JSONResponse(
status_code=500, content={"available": False, "error": str(resp.text)}
)
elif provider in ("openrouter", "openrouter_premium"):
api_key = _key(provider_config.api_key, "OPENROUTER_API_KEY")
@@ -1325,59 +1307,6 @@ async def test_send_email(
)
@router.get("/providers/ollama/models")
async def list_ollama_models(
base_url: Optional[str] = Query(None),
admin_id: str = Depends(require_admin),
):
"""List available models from Ollama server. Accepts optional base_url query param
so the frontend can pass the URL currently being edited (before save)."""
import requests
from config import config as app_config
settings = load_settings()
resolved = (
base_url
or settings.ollama.base_url
or app_config.OLLAMA_BASE_URL
or "http://localhost:11434"
)
try:
response = requests.get(f"{resolved}/api/tags", timeout=5)
if response.ok:
data = response.json()
models = []
for model in data.get("models", []):
models.append(
{
"name": model.get("name", ""),
"size": model.get("size", 0),
"modified_at": model.get("modified_at", ""),
}
)
return JSONResponse(status_code=200, content={"data": models, "meta": {}})
return JSONResponse(
status_code=500,
content={
"error": "OLLAMA_UNAVAILABLE",
"message": f"Ollama returned: {response.text}",
},
)
except requests.exceptions.ConnectionError:
return JSONResponse(
status_code=503,
content={
"error": "OLLAMA_CONNECTION_ERROR",
"message": f"Cannot connect to Ollama at {resolved}",
},
)
except Exception as e:
logger.error(f"List Ollama models failed: {e}")
return JSONResponse(
status_code=500,
content={"error": "INTERNAL_ERROR", "message": str(e)},
)
@router.get("/providers/openai/models")