gmao/app_new/ai_config/templates/ai_config/index.html

134 lines
6.4 KiB
HTML
Raw Normal View History

2026-08-14 18:02:25 +02:00
{% extends "base.html" %}
{% block title %}Configuration IA - GMAO{% endblock %}
{% block content %}
<div class="container-fluid">
<nav aria-label="breadcrumb" class="mb-3">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{{ url_for('dashboard.index') }}">Tableau de bord</a></li>
<li class="breadcrumb-item active">Configuration IA</li>
</ol>
</nav>
<h2 class="h4 mb-3"><i class="bi bi-robot"></i> Configuration IA (OpenRouter)</h2>
<div class="alert alert-warning"><i class="bi bi-person-check"></i> <strong>Validation humaine obligatoire :</strong> lIA produit uniquement des propositions. Elle ne crée, ne modifie et ne clôture jamais automatiquement une intervention.</div>
2026-08-14 18:02:25 +02:00
<div class="row">
<div class="col-lg-8">
<div class="card border-0 shadow-sm mb-3">
<div class="card-body">
<h6 class="text-muted"><i class="bi bi-key"></i> Cle API OpenRouter</h6>
<form method="POST" action="{{ url_for('ai_config.save') }}">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<div class="mb-3">
<label class="form-label">Cle API</label>
<input type="password" name="api_key" class="form-control"
value="{{ masked_key if has_key else '' }}"
placeholder="sk-or-v1-...">
<small class="text-muted">
{% if has_key %}
Cle configuree ({{ masked_key }}). Laisser tel quel pour conserver.
{% else %}
Non configuree. Obtenez votre cle sur <a href="https://openrouter.ai/keys" target="_blank">openrouter.ai/keys</a>.
{% endif %}
</small>
</div>
<div class="mb-3">
<label class="form-label">Nom du modele</label>
<input type="text" name="model" class="form-control"
value="{{ model }}"
placeholder="ex: poolside/laguna-m.1:free"
required>
<small class="text-muted">
Liste des modeles : <a href="https://openrouter.ai/models" target="_blank">openrouter.ai/models</a>.
Modeles gratuits recommandes : <code>poolside/laguna-m.1:free</code>, <code>z-ai/glm-4.5-air:free</code>, <code>meta-llama/llama-3.1-8b-instruct:free</code>
</small>
</div>
<div class="d-flex gap-2">
<button type="submit" class="btn btn-primary">
<i class="bi bi-check-circle"></i> Enregistrer
</button>
<button type="button" class="btn btn-outline-info" id="btn-test-model">
<i class="bi bi-play-circle"></i> Tester le modele
</button>
</div>
</form>
</div>
</div>
<!-- Statut du modele -->
<div class="card border-0 shadow-sm mb-3">
<div class="card-body">
<h6 class="text-muted"><i class="bi bi-activity"></i> Statut du modele</h6>
{% if model_status == 'ok' %}
<div class="alert alert-success mb-0">
<i class="bi bi-check-circle"></i> Le modele <strong>{{ model }}</strong> repond correctement.
</div>
{% elif model_status == 'error' %}
<div class="alert alert-danger mb-0">
<i class="bi bi-x-circle"></i> Erreur : {{ model_error }}
<br><small class="text-muted">Le modele <code>{{ model }}</code> ne semble pas exister ou la cle API est invalide.</small>
</div>
{% else %}
<div class="alert alert-secondary mb-0">
<i class="bi bi-question-circle"></i> Non teste. Cliquez sur "Tester le modele".
</div>
{% endif %}
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card border-0 shadow-sm">
<div class="card-body">
<h6 class="text-muted"><i class="bi bi-info-circle"></i> Aide</h6>
<p class="small">
L'IA analyse les emails Outlook et les messages ENT pour creer des interpretations.
Ces interpretations sont ensuite validees dans la page <a href="{{ url_for('messagerie.index') }}">Messagerie</a>.
</p>
<p class="small text-muted">
Le modele doit etre un modele de chat compatible OpenAI disponible sur OpenRouter.
Les modeles gratuits ont un suffixe <code>:free</code>.
</p>
<p class="small text-muted">
Si le modele n'existe plus, une alerte s'affiche sur le tableau de bord principal.
</p>
</div>
</div>
</div>
</div>
</div>
<script>
document.getElementById('btn-test-model').addEventListener('click', async function() {
const btn = this;
const original = btn.innerHTML;
btn.disabled = true;
btn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> Test...';
const model = document.querySelector('input[name="model"]').value;
try {
const r = await fetch('/ai-config/api/test-model', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({model: model})
});
const d = await r.json();
if (d.success) {
alert('Modele OK ! Reponse: ' + d.response);
} else {
alert('Erreur: ' + d.error);
}
} catch(e) {
alert('Erreur: ' + e.message);
}
btn.disabled = false;
btn.innerHTML = original;
});
</script>
{% endblock %}