modif selection chatbot

This commit is contained in:
nicoboy
2026-01-05 09:25:37 +01:00
parent e3d392bf08
commit f199ce0653
4 changed files with 212 additions and 20 deletions

View File

@ -28,13 +28,13 @@ function openAddKeyModal(provider = null) {
document.getElementById('keyAction').value = 'add';
editMode = false;
// Important : activer le select AVANT de définir la valeur
providerSelect.disabled = false;
// Pre-select provider if provided
if (provider) {
providerSelect.value = provider;
updateModelsList();
providerSelect.disabled = false;
} else {
providerSelect.disabled = false;
providerSelect.dispatchEvent(new Event('change')); // Trigger updateModelsList
}
title.textContent = 'Ajouter une clé API';
@ -282,6 +282,98 @@ function deleteKey(provider) {
});
}
// ========== Set Default Provider ==========
function setAsDefault(provider, model) {
const formData = new FormData();
formData.append('action', 'set_default');
formData.append('provider', provider);
formData.append('model', model);
fetch('chatbot_api_ajax.php', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
showToast(data.message || 'Provider par défaut mis à jour', 'success');
setTimeout(() => {
window.location.reload();
}, 1000);
} else {
showToast(data.error || 'Erreur', 'error');
}
})
.catch(error => {
console.error('Error:', error);
showToast('Erreur de connexion', 'error');
});
}
// ========== Configure Ollama ==========
function configureOllama() {
const availableModels = models['ollama'] || [];
if (availableModels.length === 0) {
showToast('Aucun modèle Ollama disponible', 'error');
return;
}
// Créer une liste des modèles
let modelOptions = '<select id="ollama-model-select" style="width: 100%; padding: 0.5rem; margin: 1rem 0; border: 2px solid #e2e8f0; border-radius: 8px;">';
availableModels.forEach(model => {
modelOptions += `<option value="${model.model_id}">${model.display_name}</option>`;
});
modelOptions += '</select>';
// Simple prompt
const modelHtml = `
<div style="padding: 1rem;">
<p style="margin-bottom: 1rem;">Choisir le modèle Ollama par défaut :</p>
${modelOptions}
</div>
`;
// Utiliser une confirm box simple pour l'instant
// (dans une vraie app, utiliser le modal existant)
const modal = document.getElementById('keyModal');
const modalContent = modal.querySelector('.modal-content');
const originalContent = modalContent.innerHTML;
modalContent.innerHTML = `
<div class="modal-header">
<h2>Configuration Ollama</h2>
<button class="modal-close" onclick="closeKeyModal()">×</button>
</div>
<div style="padding: 1.5rem;">
<p style="margin-bottom: 1rem;">Choisir le modèle Ollama à utiliser par défaut :</p>
<select id="ollama-model-select" style="width: 100%; padding: 0.75rem; border: 2px solid #e2e8f0; border-radius: 8px; font-family: 'JetBrains Mono', monospace;">
${availableModels.map(m => `<option value="${m.model_id}">${m.display_name}</option>`).join('')}
</select>
<div style="display: flex; gap: 1rem; justify-content: flex-end; margin-top: 1.5rem; padding-top: 1.5rem; border-top: 2px solid #e2e8f0;">
<button class="btn-secondary" onclick="closeKeyModal(); document.querySelector('.modal-content').innerHTML = \`${originalContent.replace(/`/g, '\\`')}\`;">Annuler</button>
<button class="btn-primary" onclick="saveOllamaConfig()">💾 Enregistrer</button>
</div>
</div>
`;
modal.classList.add('show');
}
function saveOllamaConfig() {
const select = document.getElementById('ollama-model-select');
const model = select.value;
if (!model) {
showToast('Veuillez sélectionner un modèle', 'error');
return;
}
setAsDefault('ollama', model);
}
// ========== Toast Notifications ==========
function showToast(message, type = 'info') {

View File

@ -161,6 +161,35 @@ try {
]);
break;
case 'set_default':
// Définir le provider par défaut
$provider = $_POST['provider'] ?? null;
$model = $_POST['model'] ?? null;
if (!$provider || !$model) {
throw new Exception('Paramètres manquants');
}
$db = Database::getInstance();
// Upsert dans chatbot_default_provider
$result = $db->query(
"INSERT INTO chatbot_default_provider (id_enseignant, provider, model_default)
VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE provider = VALUES(provider), model_default = VALUES(model_default)",
[$user['id_utilisateur'], $provider, $model]
);
if (!$result) {
throw new Exception('Erreur lors de la mise à jour');
}
echo json_encode([
'success' => true,
'message' => 'Provider par défaut mis à jour'
]);
break;
case 'stats':
// Récupérer les statistiques d'utilisation
$db = Database::getInstance();

View File

@ -21,19 +21,23 @@ $db = Database::getInstance();
// Récupérer les clés API de l'enseignant
$api_keys = APIKeyManager::listKeys($user['id_utilisateur']);
// Déterminer le provider par défaut (premier actif ou ollama)
$default_provider = null;
foreach ($api_keys as $key) {
if ($key['is_active']) {
$default_provider = $key['provider'];
break; // Premier actif trouvé
}
}
// Si aucune clé active, Ollama par défaut
if (!$default_provider) {
$default_provider = 'ollama';
// Récupérer le provider par défaut configuré
$default_config = $db->fetchOne(
"SELECT provider, model_default FROM chatbot_default_provider WHERE id_enseignant = ?",
[$user['id_utilisateur']]
);
// Si pas de config, initialiser avec Ollama
if (!$default_config) {
$db->query(
"INSERT INTO chatbot_default_provider (id_enseignant, provider, model_default) VALUES (?, 'ollama', 'ministral-3:3b')",
[$user['id_utilisateur']]
);
$default_config = ['provider' => 'ollama', 'model_default' => 'ministral-3:3b'];
}
$default_provider = $default_config['provider'];
$default_model = $default_config['model_default'];
// Récupérer les modèles disponibles groupés par provider
$models_by_provider = [];
@ -165,10 +169,7 @@ $stats_detail = $db->fetchAll(
</div>
<div class="key-status">
<?php if ($is_active): ?>
<span class="status-badge active">🟢 Active</span>
<?php if ($default_provider === $provider_id): ?>
<span class="status-badge default">✨ Par défaut</span>
<?php endif; ?>
<span class="status-badge active">🟢 Active</span>
<?php elseif ($is_configured): ?>
<span class="status-badge inactive">🟠 Désactivée</span>
<?php else: ?>
@ -178,7 +179,36 @@ $stats_detail = $db->fetchAll(
</div>
<div class="key-body">
<?php if ($is_configured): ?>
<?php if ($provider_id === 'ollama'): ?>
<!-- Card spéciale Ollama (pas de clé API nécessaire) -->
<div class="key-info">
<div class="info-row">
<span class="label">Type :</span>
<span class="value">🏠 Local (Jetson)</span>
</div>
<div class="info-row">
<span class="label">Modèle actuel :</span>
<span class="value"><?= $default_provider === 'ollama' ? htmlspecialchars($default_model) : 'ministral-3:3b' ?></span>
</div>
<div class="info-row">
<span class="label">Coût :</span>
<span class="value">Gratuit ✅</span>
</div>
</div>
<div class="key-actions">
<button class="btn-secondary btn-sm" onclick="testConnection('ollama')">
🔍 Tester
</button>
<button class="btn-secondary btn-sm" onclick="configureOllama()">
⚙️ Changer le modèle
</button>
<?php if ($default_provider !== 'ollama'): ?>
<button class="btn-primary btn-sm" onclick="setAsDefault('ollama', 'ministral-3:3b')">
⭐ Définir par défaut
</button>
<?php endif; ?>
</div>
<?php elseif ($is_configured): ?>
<div class="key-info">
<div class="info-row">
<span class="label">Modèle par défaut :</span>
@ -209,6 +239,11 @@ $stats_detail = $db->fetchAll(
<button class="btn-secondary btn-sm" onclick="editKey('<?= $provider_id ?>')">
✏️ Modifier
</button>
<?php if ($default_provider !== $provider_id): ?>
<button class="btn-primary btn-sm" onclick="setAsDefault('<?= $provider_id ?>', '<?= htmlspecialchars($key_info['model_default']) ?>')">
⭐ Définir par défaut
</button>
<?php endif; ?>
<button class="btn-danger btn-sm" onclick="deleteKey('<?= $provider_id ?>')">
🗑️ Supprimer
</button>

View File

@ -0,0 +1,36 @@
-- ============================================
-- WebVal - Configuration provider par défaut
-- Table pour stocker le choix de l'enseignant
-- ============================================
-- Table de configuration par défaut par enseignant
CREATE TABLE IF NOT EXISTS chatbot_default_provider (
id INT AUTO_INCREMENT PRIMARY KEY,
id_enseignant INT NOT NULL,
provider VARCHAR(50) NOT NULL,
model_default VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (id_enseignant) REFERENCES utilisateurs(id_utilisateur) ON DELETE CASCADE,
UNIQUE KEY unique_enseignant (id_enseignant)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Initialiser Ollama comme défaut pour les enseignants existants
INSERT IGNORE INTO chatbot_default_provider (id_enseignant, provider, model_default)
SELECT DISTINCT id_utilisateur, 'ollama', 'ministral-3:3b'
FROM utilisateurs
WHERE id_type = 1; -- Type enseignant
-- Mettre à jour pour ceux qui ont déjà une clé cloud active
UPDATE chatbot_default_provider cdp
JOIN (
SELECT id_enseignant, provider, model_default
FROM api_keys
WHERE is_active = 1
ORDER BY created_at ASC
LIMIT 1
) ak ON cdp.id_enseignant = ak.id_enseignant
SET cdp.provider = ak.provider,
cdp.model_default = ak.model_default;
SELECT '✅ Table chatbot_default_provider créée et initialisée' as Status;