feat(settings): bouton "Réinitialiser" fournisseur IA + correctif JS (page complète)
FlowDeck CI / test (push) Failing after 16s
FlowDeck CI / docker (push) Skipped

- Nouveau bouton « 🗑 Réinitialiser » dans Réglages → Agent & IA (réservé aux
  admins) : bascule le fournisseur par défaut sur « hors-ligne » et efface la
  clé API/base/état vérifié stockés (clear_keys dans set_llm_config).
- Confirmation avant suppression des clés API utilisateur (deleteUserKey).
- Correctif : chaîne JS de confirm("…") sur deux lignes provoquait une erreur
  de syntaxe → le script alpine:init ne s'exécutait pas et la page paramètres
  restait figée sur « Agent & AI » ; la chaîne est désormais sur une ligne.
This commit is contained in:
2026-09-07 20:48:25 -04:00
parent 8b0a0aea3a
commit 32c81f156d
3 changed files with 37 additions and 1 deletions
+1
View File
@@ -850,6 +850,7 @@ async def update_provider_config(request: Request):
model=(body.get("model") or "").strip() or None,
api_key=body.get("api_key"),
api_base=(body.get("api_base") or "").strip() or None,
clear_keys=(provider == "offline"),
)
llm = LLMClient()
return {
+8 -1
View File
@@ -80,7 +80,8 @@ def get_llm_config() -> dict:
def set_llm_config(*, provider: str | None = None, model: str | None = None,
api_key: str | None = None, api_base: str | None = None) -> dict:
api_key: str | None = None, api_base: str | None = None,
clear_keys: bool = False) -> dict:
"""Upsert the runtime LLM config row (id=1) and return the new effective config.
An empty `api_key`/`api_base` keeps the stored value (so an admin can tweak
@@ -103,6 +104,12 @@ def set_llm_config(*, provider: str | None = None, model: str | None = None,
cfg["last_error"] = ""
if api_base is not None and api_base.strip():
cfg["api_base"] = api_base.strip()
if clear_keys:
cfg["api_key"] = ""
cfg["api_base"] = ""
cfg["verified"] = 0
cfg["verified_model"] = ""
cfg["last_error"] = ""
with get_conn() as conn:
conn.execute(
+28
View File
@@ -600,6 +600,7 @@
<span x-show="!llmTesting">🔌 Tester la connexion</span>
<span x-show="llmTesting">Test…</span>
</button>
<button class="btn" @click="resetGlobalLlm()" :disabled="llmSaving" x-show="llmDefaultProvider !== 'offline'" style="font-size:13px;color:var(--danger);">🗑 Réinitialiser</button>
</div>
<div style="margin-top:10px;font-size:12.5px;">
<span x-show="llmMsg" x-text="llmMsg" :style="{color: llmMsgOk ? 'var(--toast-success-bg)' : 'var(--danger)'}"></span>
@@ -1107,6 +1108,8 @@ document.addEventListener('alpine:init', function() {
finally { f.testing = false; }
},
async deleteUserKey(id) {
var pname = id.charAt(0).toUpperCase() + id.slice(1);
if (!confirm('Supprimer la clé API pour ' + pname + ' ?\nLe fournisseur ne sera plus disponible dans le panneau Agent.')) return;
var f = this.keyForm(id);
f.deleting = true; f.msg = ''; f.ok = false;
try {
@@ -1185,6 +1188,31 @@ document.addEventListener('alpine:init', function() {
} catch(e) { this.llmMsg = 'Erreur réseau'; }
finally { this.llmSaving = false; }
},
async resetGlobalLlm() {
if (!confirm("Réinitialiser le fournisseur par défaut à « hors-ligne » ?\nTous les utilisateurs perdront l'accès au fournisseur IA actuel.")) return;
this.llmSaving = true;
this.llmMsg = ''; this.llmMsgOk = false;
try {
var r = await this.adminFetch('/api/agent/providers', {
method: 'PATCH',
headers: {'Content-Type':'application/json'},
body: JSON.stringify({provider: 'offline', model: '', api_key: '', api_base: ''})
});
var d = await r.json();
if (r.ok) {
this.llmForm = {provider: 'offline', model: '', api_key: '', api_base: ''};
this.llmHasKey = false;
this.llmDefaultProvider = 'offline';
this.llmProviderModels = [];
this.llmMsgOk = true;
this.llmMsg = 'Fournisseur réinitialisé : mode hors-ligne actif.';
this.syncLlmStatus();
} else {
this.llmMsg = d.detail || 'Erreur lors de la réinitialisation';
}
} catch(e) { this.llmMsg = 'Erreur réseau'; }
finally { this.llmSaving = false; }
},
async testLlm() {
if (!this.llmForm.provider) return;
this.llmTesting = true;