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