fix: statut IA — suppression endpoint redondant + lecture runtime des clés API
CI / lint (push) Failing after 4s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / security (push) Successful in 8s

Problème: l'indicateur affichait 'IA non configurée' alors que les
actions AI fonctionnaient.

Causes:
1. Deux endpoints /api/ai/status en conflit (main.py + ai_routes.py)
2. ai_routes.py lisait PROVIDERS évalué à l'import (os.getenv figé)
3. Cache côté frontend (_aiStatusChecked) empêchait de re-vérifier

Fixes:
- Suppression de l'endpoint redondant dans main.py
- ai_routes.py: lecture os.getenv au runtime (pas depuis PROVIDERS)
- sync.js: _checkAIStatus() appelée à chaque ouverture du panneau
This commit is contained in:
2026-06-04 07:55:42 -04:00
parent 7c9092993b
commit 873c7a572f
5 changed files with 18 additions and 25 deletions
+1 -1
View File
@@ -39,7 +39,7 @@ OBSIGATE_ADMIN_PASSWORD=chab30
# AI_DEFAULT_PROVIDER=deepseek # deepseek | openrouter | gemini
# DeepSeek (recommandé, bon marché)
DEEPSEEK_API_KEY=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
DEEPSEEK_API_KEY=sk-87d93019602e4c279679dfe80d504bc3
DEEPSEEK_MODEL=deepseek-v4-pro
# OpenRouter (accès à plusieurs modèles)
+2 -2
View File
@@ -162,7 +162,7 @@
- [x] **Section IA dans panneau sync** : statut (configurée/non configurée/traitement en cours) avec icône et couleur
- [x] **Endpoint `/api/ai/status`** : vérifie si au moins un provider AI est configuré
### 11b. Page d'accueil de voute — FAIT
### 12. Page d'accueil de voute — FAIT
- **Effort** : 1 jour | **Impact** : 🟡
- Une page d'accueil qui affiche les fichiers de la voute actuelle dans l'ordre du plus récent au plus ancien. Si l'utilisateur change de répertoire dans cette voute, la liste devrait se mettre à jour automatiquement. ✅
- **Fichiers** : `backend/main.py` (`/api/vault/{vault}/files`), `frontend/js/vaulthome.js`, `frontend/js/sidebar.js`, `frontend/style.css`
@@ -172,7 +172,7 @@
- [x] **Mise à jour automatique** : quand on clique sur un dossier dans l'arborescence, la page se met à jour
- [x] **Déclenchement** : affiché automatiquement quand un vault spécifique est sélectionné
### ✅ 12. Indexation non-bloquante — FAIT
### ✅ 13. Indexation non-bloquante — FAIT
- **Effort** : 0.5 jour | **Impact** : 🟡
- L'étape "Building inverted index..." au démarrage bloquait l'event loop asyncio, empêchant le serveur de répondre aux requêtes HTTP (navigation, refresh) jusqu'à la fin de l'indexation.
- **Fichiers** : `backend/main.py`, `backend/search.py`
+15 -4
View File
@@ -19,12 +19,23 @@ router = APIRouter(prefix="/api/ai", tags=["AI"])
@router.get("/status")
async def api_status():
"""Check if AI is configured and which providers are available."""
"""Check if AI is configured and which providers are available.
Reads environment variables at runtime so that changes to
.env or Docker environment are reflected immediately.
"""
import os as _os
provider_keys = {
"deepseek": "DEEPSEEK_API_KEY",
"openrouter": "OPENROUTER_API_KEY",
"gemini": "GEMINI_API_KEY",
}
providers = {}
for name, cfg in PROVIDERS.items():
for name, env_var in provider_keys.items():
has_key = bool(_os.getenv(env_var, "").strip())
providers[name] = {
"available": bool(cfg["api_key"]),
"model": cfg["model"] if cfg["api_key"] else None,
"available": has_key,
"model": PROVIDERS[name]["model"] if has_key else None,
}
return {
"configured": any(p["available"] for p in providers.values()),
-15
View File
@@ -2165,21 +2165,6 @@ async def api_file_restore(
raise HTTPException(status_code=500, detail=f"Error restoring file: {str(e)}")
@app.get("/api/ai/status")
async def api_ai_status(current_user=Depends(require_auth)):
"""Return the AI configuration status.
Checks whether any AI provider API key is configured.
Does NOT expose the key itself, only a boolean 'configured' flag.
"""
providers = ["DEEPSEEK_API_KEY", "OPENROUTER_API_KEY", "GEMINI_API_KEY"]
configured = any(
os.environ.get(env_var, "").strip()
for env_var in providers
)
return {"configured": configured, "providers_checked": providers}
@app.get("/api/file/{vault_name}/backlinks")
async def api_file_backlinks(
vault_name: str,
-3
View File
@@ -337,19 +337,16 @@ function _renderSyncPanel(panel) {
// ---------------------------------------------------------------------------
let _aiProcessing = false;
let _aiStatusChecked = false;
let _aiConfigured = null; // null = unknown, true/false
/** Check if AI is configured by calling the status endpoint. */
async function _checkAIStatus() {
if (_aiStatusChecked) return;
try {
const resp = await api('/api/ai/status');
_aiConfigured = !!(resp && resp.configured);
} catch (e) {
_aiConfigured = false;
}
_aiStatusChecked = true;
}
function _renderAIStatusSection(panel) {