Files
wevads-platform/scripts/hamid-selector.php
2026-02-26 04:53:11 +01:00

237 lines
6.7 KiB
PHP
Executable File

<?php
/**
* Composant Sélecteur Multi-IA pour WEVAL MIND
* À inclure dans les interfaces
*/
require_once __DIR__ . '/hamid-brain.php';
$brain = new HamidBrain();
$providers = $brain->getAvailableProviders();
$defaultProvider = $brain->getConfig('default_provider', 'groq');
?>
<!-- CSS du sélecteur -->
<style>
.ai-selector-container {
display: flex;
align-items: center;
gap: 10px;
}
.ai-selector {
position: relative;
min-width: 160px;
}
.ai-selector select {
appearance: none;
width: 100%;
padding: 8px 36px 8px 12px;
background: var(--bg-input, #3c3c3c);
border: 1px solid var(--border, #555);
border-radius: 8px;
color: var(--text, #fff);
font-size: 13px;
cursor: pointer;
outline: none;
transition: all 0.2s;
}
.ai-selector select:hover {
border-color: var(--accent, #0078d4);
}
.ai-selector select:focus {
border-color: var(--accent, #0078d4);
box-shadow: 0 0 0 3px rgba(0, 120, 212, 0.2);
}
.ai-selector::after {
content: '▼';
position: absolute;
right: 12px;
top: 50%;
transform: translateY(-50%);
font-size: 10px;
color: var(--text-dim, #888);
pointer-events: none;
}
.ai-selector select option {
background: var(--bg-dark, #1e1e1e);
color: var(--text, #fff);
padding: 8px;
}
.ai-selector select option:disabled {
color: var(--text-dim, #666);
}
.ai-status {
display: flex;
align-items: center;
gap: 6px;
font-size: 12px;
color: var(--text-dim, #888);
}
.ai-status .dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--success, #4caf50);
}
.ai-status .dot.warning { background: var(--warning, #ff9800); }
.ai-status .dot.error { background: var(--error, #f44336); }
.ai-auto-toggle {
display: flex;
align-items: center;
gap: 6px;
font-size: 12px;
color: var(--text-dim, #888);
}
.ai-auto-toggle input[type="checkbox"] {
width: 16px;
height: 16px;
cursor: pointer;
}
.ai-badge {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 2px 8px;
border-radius: 10px;
font-size: 11px;
font-weight: 500;
}
.ai-badge.free { background: #1b5e20; color: #a5d6a7; }
.ai-badge.paid { background: #e65100; color: #ffcc80; }
</style>
<!-- HTML du sélecteur -->
<div class="ai-selector-container" id="aiSelectorContainer">
<div class="ai-selector">
<select id="aiProviderSelect" onchange="onProviderChange(this.value)">
<optgroup label="🆓 Gratuits">
<?php foreach ($providers as $id => $p): ?>
<?php if ($p['free'] && $p['type'] === 'cloud'): ?>
<option value="<?= $id ?>" <?= $id === $defaultProvider ? 'selected' : '' ?> <?= !$p['configured'] ? 'disabled' : '' ?>>
<?= $p['icon'] ?> <?= $p['name'] ?> <?= !$p['configured'] ? '(non configuré)' : '' ?>
</option>
<?php endif; ?>
<?php endforeach; ?>
</optgroup>
<optgroup label="💰 Premium">
<?php foreach ($providers as $id => $p): ?>
<?php if (!$p['free'] && $p['type'] === 'cloud'): ?>
<option value="<?= $id ?>" <?= $id === $defaultProvider ? 'selected' : '' ?> <?= !$p['configured'] ? 'disabled' : '' ?>>
<?= $p['icon'] ?> <?= $p['name'] ?> <?= !$p['configured'] ? '(non configuré)' : '' ?>
</option>
<?php endif; ?>
<?php endforeach; ?>
</optgroup>
<optgroup label="🏠 Local">
<?php foreach ($providers as $id => $p): ?>
<?php if ($p['type'] === 'local'): ?>
<option value="<?= $id ?>" <?= $id === $defaultProvider ? 'selected' : '' ?> <?= !$p['configured'] ? 'disabled' : '' ?>>
<?= $p['icon'] ?> <?= $p['name'] ?> <?= !$p['configured'] ? '(non configuré)' : '' ?>
</option>
<?php endif; ?>
<?php endforeach; ?>
</optgroup>
</select>
</div>
<div class="ai-auto-toggle" title="Si le provider choisi échoue, essayer automatiquement les autres">
<input type="checkbox" id="aiAutoFallback" checked>
<label for="aiAutoFallback">Auto-fallback</label>
</div>
<div class="ai-status" id="aiStatus">
<span class="dot"></span>
<span id="aiStatusText">Prêt</span>
</div>
</div>
<!-- JavaScript -->
<script>
const AI_PROVIDERS = <?= json_encode($providers) ?>;
let currentProvider = '<?= $defaultProvider ?>';
let autoFallback = true;
function onProviderChange(provider) {
currentProvider = provider;
const p = AI_PROVIDERS[provider];
updateAIStatus('ready', `${p.icon} ${p.name}`);
console.log('Provider changé:', provider);
}
function updateAIStatus(status, text) {
const dot = document.querySelector('#aiStatus .dot');
const statusText = document.getElementById('aiStatusText');
dot.className = 'dot';
if (status === 'loading') {
dot.classList.add('warning');
statusText.textContent = text || 'Chargement...';
} else if (status === 'error') {
dot.classList.add('error');
statusText.textContent = text || 'Erreur';
} else {
statusText.textContent = text || 'Prêt';
}
}
function getSelectedProvider() {
return document.getElementById('aiProviderSelect').value;
}
function isAutoFallbackEnabled() {
return document.getElementById('aiAutoFallback').checked;
}
// API call helper
async function callHamidBrain(message, toolsContext = '') {
const provider = getSelectedProvider();
const autoFb = isAutoFallbackEnabled();
updateAIStatus('loading', 'Réflexion...');
try {
const res = await fetch('/hamid-brain.php', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
message: message,
provider: provider,
tools_context: toolsContext,
auto_fallback: autoFb
})
});
const data = await res.json();
if (data.success) {
const usedProvider = AI_PROVIDERS[data.provider];
updateAIStatus('ready', `${usedProvider?.icon || '🤖'} ${usedProvider?.name || data.provider}`);
if (data.fallback_used) {
console.log('Fallback utilisé:', data.provider);
}
} else {
updateAIStatus('error', 'Erreur');
}
return data;
} catch (e) {
updateAIStatus('error', 'Erreur connexion');
return {success: false, error: e.message};
}
}
</script>