515 lines
28 KiB
PHP
515 lines
28 KiB
PHP
<?php
|
|
// === NOUVEAUX OUTILS HAMID ULTRA MAX++ ===
|
|
// OCR: /hamid-ocr.php
|
|
// YouTube: /hamid-youtube.php
|
|
// Email: /hamid-email.php
|
|
// Calendar: /hamid-calendar.php
|
|
// Scrape: /hamid-scrape.php
|
|
// History: /hamid-history.php
|
|
// Plugins: /hamid-plugins.php
|
|
// API: /hamid-api-public.php
|
|
require_once __DIR__ . "/hamid-providers-config.php"; ?>
|
|
<!DOCTYPE html>
|
|
<html data-theme="dark" lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>WEVAL MIND CLI - Superintelligence Terminal</title>
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
:root {
|
|
--bg-primary: #0a0a0f;
|
|
--bg-secondary: #12121a;
|
|
--bg-tertiary: #1a1a2e;
|
|
--text-primary: #00ff00;
|
|
--text-secondary: #00d4ff;
|
|
--text-muted: #666;
|
|
--accent-cyan: #22d3ee;
|
|
--accent-purple: #a78bfa;
|
|
--accent-pink: #ff79c6;
|
|
--border-color: #333;
|
|
}
|
|
body { font-family: 'Fira Code', 'Consolas', 'Monaco', monospace; background: var(--bg-primary); color: var(--text-primary); height: 100vh; display: flex; flex-direction: column; overflow: hidden; }
|
|
|
|
/* Header */
|
|
.terminal-header { background: linear-gradient(135deg, var(--bg-secondary), var(--bg-tertiary)); padding: 12px 20px; display: flex; align-items: center; gap: 15px; border-bottom: 1px solid var(--border-color); }
|
|
.terminal-header .dots { display: flex; gap: 8px; }
|
|
.terminal-header .dot { width: 14px; height: 14px; border-radius: 50%; transition: all 0.3s; cursor: pointer; }
|
|
.terminal-header .dot:hover { transform: scale(1.2); }
|
|
.terminal-header .dot.red { background: #ff5f56; }
|
|
.terminal-header .dot.yellow { background: #ffbd2e; }
|
|
.terminal-header .dot.green { background: #27c93f; }
|
|
.terminal-header .title { flex: 1; text-align: center; color: var(--text-muted); font-size: 13px; }
|
|
.terminal-header .title span { color: var(--accent-cyan); font-weight: bold; }
|
|
.terminal-header select { background: var(--bg-tertiary); color: var(--text-primary); border: 1px solid var(--border-color); padding: 8px 12px; border-radius: 6px; font-family: inherit; font-size: 12px; cursor: pointer; }
|
|
.terminal-header select:hover { border-color: var(--accent-cyan); }
|
|
|
|
/* Stats Bar */
|
|
.stats-bar { background: var(--bg-secondary); padding: 8px 20px; display: flex; gap: 20px; border-bottom: 1px solid var(--border-color); font-size: 11px; color: var(--text-muted); }
|
|
.stats-bar .stat { display: flex; align-items: center; gap: 6px; }
|
|
.stats-bar .stat-value { color: var(--accent-cyan); font-weight: bold; }
|
|
.stats-bar .stat-icon { font-size: 14px; }
|
|
|
|
/* Main Terminal */
|
|
.terminal-container { flex: 1; display: flex; overflow: hidden; }
|
|
.sidebar { width: 250px; background: var(--bg-secondary); border-right: 1px solid var(--border-color); display: flex; flex-direction: column; }
|
|
.sidebar-header { padding: 15px; border-bottom: 1px solid var(--border-color); font-size: 12px; color: var(--accent-cyan); font-weight: bold; }
|
|
.sidebar-section { padding: 10px 15px; }
|
|
.sidebar-section h4 { color: var(--text-muted); font-size: 10px; text-transform: uppercase; margin-bottom: 8px; }
|
|
.sidebar-item { padding: 8px 12px; margin: 4px 0; border-radius: 6px; cursor: pointer; font-size: 12px; color: var(--text-secondary); transition: all 0.2s; display: flex; align-items: center; gap: 8px; }
|
|
.sidebar-item:hover { background: var(--bg-tertiary); color: var(--text-primary); }
|
|
.sidebar-item.active { background: var(--accent-cyan); color: var(--bg-primary); }
|
|
.history-list { flex: 1; overflow-y: auto; padding: 10px; }
|
|
.history-item { padding: 8px 10px; margin: 4px 0; border-radius: 4px; font-size: 11px; color: var(--text-muted); cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
.history-item:hover { background: var(--bg-tertiary); color: var(--text-secondary); }
|
|
|
|
/* Terminal Output */
|
|
.terminal-main { flex: 1; display: flex; flex-direction: column; }
|
|
.terminal { flex: 1; padding: 20px; overflow-y: auto; font-size: 14px; line-height: 1.8; }
|
|
.terminal::-webkit-scrollbar { width: 8px; }
|
|
.terminal::-webkit-scrollbar-track { background: var(--bg-secondary); }
|
|
.terminal::-webkit-scrollbar-thumb { background: var(--border-color); border-radius: 4px; }
|
|
.line { margin-bottom: 8px; white-space: pre-wrap; word-break: break-word; animation: fadeIn 0.3s ease; }
|
|
@keyframes fadeIn { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: translateY(0); } }
|
|
.line.input { color: var(--text-secondary); }
|
|
.line.output { color: var(--text-primary); }
|
|
.line.error { color: #ff5f56; }
|
|
.line.system { color: var(--text-muted); font-style: italic; }
|
|
.line.success { color: #27c93f; }
|
|
.line .prompt { color: var(--accent-pink); }
|
|
.line .user { color: var(--text-secondary); }
|
|
.line .time { color: var(--text-muted); font-size: 10px; margin-left: 10px; }
|
|
|
|
/* Thinking Box */
|
|
.thinking-box { background: linear-gradient(135deg, rgba(167,139,250,0.1), rgba(34,211,238,0.05)); border: 1px solid rgba(167,139,250,0.3); border-radius: 12px; margin: 10px 0; overflow: hidden; }
|
|
.thinking-header { display: flex; align-items: center; gap: 10px; padding: 12px 16px; cursor: pointer; color: var(--accent-purple); font-size: 13px; }
|
|
.thinking-header:hover { background: rgba(167,139,250,0.1); }
|
|
.thinking-header .sparkle { animation: sparkle 2s linear infinite; }
|
|
@keyframes sparkle { 0%, 100% { opacity: 0.5; transform: rotate(0deg); } 50% { opacity: 1; transform: rotate(180deg); } }
|
|
.thinking-header .chevron { margin-left: auto; transition: transform 0.3s; }
|
|
.thinking-box.expanded .chevron { transform: rotate(180deg); }
|
|
.thinking-content { max-height: 0; overflow: hidden; transition: max-height 0.4s ease; font-size: 12px; color: var(--text-muted); line-height: 1.6; }
|
|
.thinking-box.expanded .thinking-content { max-height: 300px; padding: 12px 16px; border-top: 1px solid rgba(167,139,250,0.2); overflow-y: auto; }
|
|
|
|
/* Code Blocks */
|
|
.code-block { background: var(--bg-tertiary); border: 1px solid var(--border-color); border-radius: 8px; margin: 10px 0; overflow: hidden; }
|
|
.code-header { display: flex; justify-content: space-between; align-items: center; padding: 8px 12px; background: var(--bg-secondary); border-bottom: 1px solid var(--border-color); font-size: 11px; color: var(--text-muted); }
|
|
.code-header .lang { color: var(--accent-cyan); }
|
|
.code-header .copy-btn { background: none; border: none; color: var(--text-muted); cursor: pointer; padding: 4px 8px; border-radius: 4px; }
|
|
.code-header .copy-btn:hover { background: var(--bg-tertiary); color: var(--text-primary); }
|
|
.code-content { padding: 12px; font-size: 13px; overflow-x: auto; }
|
|
.code-content pre { margin: 0; }
|
|
|
|
/* Input Line */
|
|
.input-area { background: var(--bg-secondary); border-top: 1px solid var(--border-color); padding: 15px 20px; }
|
|
.input-line { display: flex; align-items: center; background: var(--bg-tertiary); border: 1px solid var(--border-color); border-radius: 8px; padding: 12px 16px; transition: border-color 0.3s; }
|
|
.input-line:focus-within { border-color: var(--accent-cyan); box-shadow: 0 0 20px rgba(34,211,238,0.1); }
|
|
.input-line .prompt { color: var(--accent-pink); margin-right: 12px; font-weight: bold; }
|
|
.input-line input { flex: 1; background: transparent; border: none; color: var(--text-primary); font-family: inherit; font-size: 14px; outline: none; }
|
|
.input-line input::placeholder { color: var(--text-muted); }
|
|
.input-actions { display: flex; gap: 8px; margin-left: 12px; }
|
|
.input-actions button { background: var(--bg-secondary); border: 1px solid var(--border-color); color: var(--text-muted); padding: 6px 12px; border-radius: 6px; cursor: pointer; font-size: 12px; transition: all 0.2s; }
|
|
.input-actions button:hover { border-color: var(--accent-cyan); color: var(--accent-cyan); }
|
|
.input-actions button.primary { background: var(--accent-cyan); border-color: var(--accent-cyan); color: var(--bg-primary); }
|
|
.input-actions button.primary:hover { background: #06b6d4; }
|
|
|
|
/* Shortcuts */
|
|
.shortcuts { display: flex; gap: 15px; margin-top: 10px; font-size: 11px; color: var(--text-muted); }
|
|
.shortcut { display: flex; align-items: center; gap: 6px; }
|
|
.shortcut kbd { background: var(--bg-tertiary); padding: 2px 6px; border-radius: 4px; font-family: inherit; }
|
|
|
|
/* ASCII Art */
|
|
.ascii-art { color: var(--accent-cyan); font-size: 10px; line-height: 1.2; margin-bottom: 20px; opacity: 0.8; }
|
|
|
|
/* Loading Animation */
|
|
.loading { display: flex; align-items: center; gap: 8px; color: var(--text-muted); }
|
|
.loading-dots { display: flex; gap: 4px; }
|
|
.loading-dots span { width: 6px; height: 6px; background: var(--accent-cyan); border-radius: 50%; animation: bounce 1.4s infinite ease-in-out both; }
|
|
.loading-dots span:nth-child(1) { animation-delay: -0.32s; }
|
|
.loading-dots span:nth-child(2) { animation-delay: -0.16s; }
|
|
@keyframes bounce { 0%, 80%, 100% { transform: scale(0); } 40% { transform: scale(1); } }
|
|
|
|
/* Mobile */
|
|
@media (max-width: 768px) {
|
|
.sidebar { display: none; }
|
|
.stats-bar { flex-wrap: wrap; gap: 10px; }
|
|
}
|
|
</style>
|
|
|
|
</head>
|
|
<body>
|
|
<div class="terminal-header">
|
|
<div class="dots">
|
|
<div class="dot red" title="Fermer"></div>
|
|
<div class="dot yellow" title="Réduire"></div>
|
|
<div class="dot green" title="Agrandir"></div>
|
|
</div>
|
|
<div class="title">hamid@wevads:~ <span>WEVAL MIND CLI v3.0</span></div>
|
|
<?php
|
|
// === NOUVEAUX OUTILS HAMID ULTRA MAX++ ===
|
|
// OCR: /hamid-ocr.php
|
|
// YouTube: /hamid-youtube.php
|
|
// Email: /hamid-email.php
|
|
// Calendar: /hamid-calendar.php
|
|
// Scrape: /hamid-scrape.php
|
|
// History: /hamid-history.php
|
|
// Plugins: /hamid-plugins.php
|
|
// API: /hamid-api-public.php
|
|
echo hamid_providers_dropdown("cerebras", "provider", ""); ?>
|
|
</div>
|
|
|
|
<div class="stats-bar">
|
|
<div class="stat"><span class="stat-icon">🧠</span> Provider: <span class="stat-value" id="currentProvider">cerebras</span></div>
|
|
<div class="stat"><span class="stat-icon">📚</span> KB: <span class="stat-value">141 entries</span></div>
|
|
<div class="stat"><span class="stat-icon">⚡</span> Latence: <span class="stat-value" id="latency">--</span></div>
|
|
<div class="stat"><span class="stat-icon">💬</span> Session: <span class="stat-value" id="msgCount">0</span> msgs</div>
|
|
<div class="stat"><span class="stat-icon">🕐</span> <span class="stat-value" id="clock">--:--:--</span></div>
|
|
</div>
|
|
|
|
<div class="terminal-container">
|
|
<div class="sidebar">
|
|
<div class="sidebar-header">📁 NAVIGATION</div>
|
|
<div class="sidebar-section">
|
|
<h4>Commandes Rapides</h4>
|
|
<div class="sidebar-item" onclick="quickCmd('help')">📖 Aide</div>
|
|
<div class="sidebar-item" onclick="quickCmd('status')">📊 Status</div>
|
|
<div class="sidebar-item" onclick="quickCmd('providers')">🔌 Providers</div>
|
|
<div class="sidebar-item" onclick="quickCmd('kb search')">🔍 Recherche KB</div>
|
|
<div class="sidebar-item" onclick="quickCmd('clear')">🧹 Clear</div>
|
|
</div>
|
|
<div class="sidebar-section">
|
|
<h4>Actions</h4>
|
|
<div class="sidebar-item" onclick="exportHistory()">💾 Exporter</div>
|
|
<div class="sidebar-item" onclick="toggleTheme()">🎨 Thème</div>
|
|
<div class="sidebar-item" onclick="openFullscreen()">🖥️ Fullscreen</div>
|
|
</div>
|
|
<div class="sidebar-section">
|
|
<h4>Historique</h4>
|
|
</div>
|
|
<div class="history-list" id="historyList"></div>
|
|
</div>
|
|
|
|
<div class="terminal-main">
|
|
<div class="terminal" id="terminal">
|
|
<pre class="ascii-art">
|
|
██╗███████╗██╗ ██╗ █████╗ ██╗ ███╗ ███╗██╗███╗ ██╗██████╗
|
|
██║██╔════╝██║ ██║██╔══██╗██║ ████╗ ████║██║████╗ ██║██╔══██╗
|
|
█╗ ██║█████╗ ██║ ██║███████║██║ ██╔████╔██║██║██╔██╗ ██║██║ ██║
|
|
╚██╗ ██╔╝██╔══██║██║ ██║╚██╔╝██║██║██║╚██╗██║██║ ██║
|
|
╚████╔╝ ██║ ██║███████╗ ██║ ╚═╝ ██║██║██║ ╚████║██████╔╝
|
|
╚══╝╚══╝ ╚══════╝ ╚═══╝ ╚═╝ ╚═╝╚══════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝╚═════╝
|
|
CLI v3.0 - Superintelligence Terminal Interface
|
|
</pre>
|
|
<div class="line system">Bienvenue dans WEVAL MIND CLI - Votre interface terminal IA avancée</div>
|
|
<div class="line system">Tapez 'help' pour la liste des commandes ou posez directement une question.</div>
|
|
<div class="line system">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</div>
|
|
</div>
|
|
|
|
<div class="input-area">
|
|
<div class="input-line">
|
|
<span class="prompt">hamid@wevads:~$</span>
|
|
<input type="text" id="input" placeholder="Entrez une commande ou une question..." autofocus autocomplete="off">
|
|
<div class="input-actions">
|
|
<button onclick="clearTerminal()">Clear</button>
|
|
<button class="primary" onclick="execute()">Envoyer ⏎</button>
|
|
</div>
|
|
</div>
|
|
<div class="shortcuts">
|
|
<div class="shortcut"><kbd>↑↓</kbd> Historique</div>
|
|
<div class="shortcut"><kbd>Tab</kbd> Autocomplete</div>
|
|
<div class="shortcut"><kbd>Ctrl+L</kbd> Clear</div>
|
|
<div class="shortcut"><kbd>Ctrl+K</kbd> Recherche KB</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const terminal = document.getElementById('terminal');
|
|
const input = document.getElementById('input');
|
|
const providerSelect = document.getElementById('provider');
|
|
const historyList = document.getElementById('historyList');
|
|
|
|
let sessionId = 'cli_' + Date.now();
|
|
let history = [];
|
|
let historyIndex = -1;
|
|
let messageCount = 0;
|
|
let isDarkTheme = true;
|
|
|
|
// Clock
|
|
setInterval(() => {
|
|
document.getElementById('clock').textContent = new Date().toLocaleTimeString('fr-FR');
|
|
}, 1000);
|
|
|
|
// Provider change
|
|
providerSelect.onchange = () => {
|
|
document.getElementById('currentProvider').textContent = providerSelect.value;
|
|
addLine(`⚡ Provider changé: ${providerSelect.value}`, 'system');
|
|
};
|
|
|
|
// Input events
|
|
input.addEventListener('keydown', e => {
|
|
if (e.key === 'Enter') { execute(); }
|
|
else if (e.key === 'ArrowUp') { navigateHistory(1); e.preventDefault(); }
|
|
else if (e.key === 'ArrowDown') { navigateHistory(-1); e.preventDefault(); }
|
|
else if (e.key === 'Tab') { autocomplete(); e.preventDefault(); }
|
|
else if (e.ctrlKey && e.key === 'l') { clearTerminal(); e.preventDefault(); }
|
|
else if (e.ctrlKey && e.key === 'k') { input.value = 'kb search '; e.preventDefault(); }
|
|
});
|
|
|
|
function navigateHistory(dir) {
|
|
if (history.length === 0) return;
|
|
historyIndex = Math.max(-1, Math.min(history.length - 1, historyIndex + dir));
|
|
input.value = historyIndex >= 0 ? history[history.length - 1 - historyIndex] : '';
|
|
}
|
|
|
|
function autocomplete() {
|
|
const cmds = ['help', 'clear', 'status', 'providers', 'kb search', 'kb add', 'export', 'theme', 'history'];
|
|
const val = input.value.toLowerCase();
|
|
const match = cmds.find(c => c.startsWith(val));
|
|
if (match) input.value = match;
|
|
}
|
|
|
|
function addLine(text, type = 'output') {
|
|
const div = document.createElement('div');
|
|
div.className = 'line ' + type;
|
|
|
|
// Format code blocks
|
|
if (text.includes('```')) {
|
|
div.innerHTML = formatCodeBlocks(text);
|
|
} else {
|
|
div.innerHTML = formatText(text);
|
|
}
|
|
|
|
terminal.appendChild(div);
|
|
terminal.scrollTop = terminal.scrollHeight;
|
|
}
|
|
|
|
function formatText(text) {
|
|
return text
|
|
.replace(/\*\*(.*?)\*\*/g, '<strong style="color:#22d3ee">$1</strong>')
|
|
.replace(/`([^`]+)`/g, '<code style="background:#1a1a2e;padding:2px 6px;border-radius:4px">$1</code>')
|
|
.replace(/\n/g, '<br>');
|
|
}
|
|
|
|
function formatCodeBlocks(text) {
|
|
return text.replace(/```(\w+)?\n?([\s\S]*?)```/g, (_, lang, code) => {
|
|
return `<div class="code-block">
|
|
<div class="code-header">
|
|
<span class="lang">${lang || 'code'}</span>
|
|
<button class="copy-btn" onclick="copyCode(this)">📋 Copier</button>
|
|
</div>
|
|
<div class="code-content"><pre>${code.trim()}</pre></div>
|
|
</div>`;
|
|
});
|
|
}
|
|
|
|
function copyCode(btn) {
|
|
const code = btn.closest('.code-block').querySelector('pre').textContent;
|
|
navigator.clipboard.writeText(code);
|
|
btn.textContent = '✅ Copié!';
|
|
setTimeout(() => btn.textContent = '📋 Copier', 2000);
|
|
}
|
|
|
|
function addThinking(text) {
|
|
const div = document.createElement('div');
|
|
div.className = 'thinking-box';
|
|
div.innerHTML = `
|
|
<div class="thinking-header" onclick="this.parentElement.classList.toggle('expanded')">
|
|
<span class="sparkle">✨</span>
|
|
<span>Réflexion de l'IA</span>
|
|
<span class="chevron">▼</span>
|
|
</div>
|
|
<div class="thinking-content">${text}</div>
|
|
`;
|
|
terminal.appendChild(div);
|
|
}
|
|
|
|
function addLoading() {
|
|
const div = document.createElement('div');
|
|
div.className = 'line loading';
|
|
div.id = 'loading';
|
|
div.innerHTML = `<span>Traitement en cours</span><div class="loading-dots"><span></span><span></span><span></span></div>`;
|
|
terminal.appendChild(div);
|
|
terminal.scrollTop = terminal.scrollHeight;
|
|
}
|
|
|
|
function removeLoading() {
|
|
const el = document.getElementById('loading');
|
|
if (el) el.remove();
|
|
}
|
|
|
|
function execute() {
|
|
const cmd = input.value.trim();
|
|
if (!cmd) return;
|
|
|
|
history.push(cmd);
|
|
historyIndex = -1;
|
|
updateHistoryList();
|
|
|
|
const time = new Date().toLocaleTimeString('fr-FR');
|
|
addLine(`<span class="prompt">hamid@wevads:~$</span> <span class="user">${cmd}</span> <span class="time">${time}</span>`, 'input');
|
|
input.value = '';
|
|
|
|
// Built-in commands
|
|
if (cmd === 'help') { showHelp(); return; }
|
|
if (cmd === 'clear') { clearTerminal(); return; }
|
|
if (cmd === 'providers') { showProviders(); return; }
|
|
if (cmd === 'status') { showStatus(); return; }
|
|
if (cmd === 'history') { showHistory(); return; }
|
|
if (cmd === 'export') { exportHistory(); return; }
|
|
if (cmd === 'theme') { toggleTheme(); return; }
|
|
if (cmd.startsWith('kb search ')) { searchKB(cmd.substring(10)); return; }
|
|
|
|
// Send to AI
|
|
sendToAI(cmd);
|
|
}
|
|
|
|
function showHelp() {
|
|
addLine('╔══════════════════════════════════════════════════════════════════╗', 'system');
|
|
addLine('║ WEVAL MIND CLI - AIDE ║', 'system');
|
|
addLine('╠══════════════════════════════════════════════════════════════════╣', 'system');
|
|
addLine('║ COMMANDES SYSTÈME ║', 'system');
|
|
addLine('║ help Affiche cette aide ║', 'system');
|
|
addLine('║ clear Efface le terminal ║', 'system');
|
|
addLine('║ status Affiche état du système ║', 'system');
|
|
addLine('║ providers Liste les providers IA ║', 'system');
|
|
addLine('║ history Affiche historique ║', 'system');
|
|
addLine('║ export Exporte la conversation ║', 'system');
|
|
addLine('║ theme Change le thème ║', 'system');
|
|
addLine('╠══════════════════════════════════════════════════════════════════╣', 'system');
|
|
addLine('║ KNOWLEDGE BASE ║', 'system');
|
|
addLine('║ kb search [terme] Recherche dans la KB ║', 'system');
|
|
addLine('╠══════════════════════════════════════════════════════════════════╣', 'system');
|
|
addLine('║ RACCOURCIS: ↑↓ Historique | Tab Auto | Ctrl+L Clear ║', 'system');
|
|
addLine('╚══════════════════════════════════════════════════════════════════╝', 'system');
|
|
}
|
|
|
|
function showStatus() {
|
|
addLine(`
|
|
|
|
Provider: ${providerSelect.value}
|
|
Session ID: ${sessionId}
|
|
Messages: ${messageCount}
|
|
KB Entries: 141
|
|
Uptime: ${Math.floor((Date.now() - parseInt(sessionId.split('_')[1])) / 1000)}s
|
|
Thème: ${isDarkTheme ? 'Sombre' : 'Clair'}`, 'system');
|
|
}
|
|
|
|
function showHistory() {
|
|
if (history.length === 0) {
|
|
addLine('Historique vide.', 'system');
|
|
return;
|
|
}
|
|
addLine('📜 HISTORIQUE DES COMMANDES\n━━━━━━━━━━━━━━━━━━━━━━━━━━━', 'system');
|
|
history.forEach((cmd, i) => addLine(` ${i + 1}. ${cmd}`, 'system'));
|
|
}
|
|
|
|
function clearTerminal() {
|
|
terminal.innerHTML = '';
|
|
addLine('Terminal effacé.', 'system');
|
|
}
|
|
|
|
function toggleTheme() {
|
|
isDarkTheme = !isDarkTheme;
|
|
document.body.style.background = isDarkTheme ? '#0a0a0f' : '#f5f5f5';
|
|
addLine(`🎨 Thème changé: ${isDarkTheme ? 'Sombre' : 'Clair'}`, 'system');
|
|
}
|
|
|
|
function exportHistory() {
|
|
const content = history.join('\n');
|
|
const blob = new Blob([content], { type: 'text/plain' });
|
|
const a = document.createElement('a');
|
|
a.href = URL.createObjectURL(blob);
|
|
a.download = `weval-cli-history-${Date.now()}.txt`;
|
|
a.click();
|
|
addLine('💾 Historique exporté!', 'success');
|
|
}
|
|
|
|
function updateHistoryList() {
|
|
historyList.innerHTML = history.slice(-10).reverse().map(cmd =>
|
|
`<div class="history-item" onclick="input.value='${cmd}'">${cmd}</div>`
|
|
).join('');
|
|
}
|
|
|
|
function quickCmd(cmd) {
|
|
input.value = cmd;
|
|
if (cmd !== 'kb search') execute();
|
|
}
|
|
|
|
function openFullscreen() {
|
|
window.open('/hamid-fullscreen.php', '_blank');
|
|
}
|
|
|
|
async function searchKB(term) {
|
|
addLoading();
|
|
try {
|
|
const res = await fetch('/hamid-api.php', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ action: 'search_kb', query: term })
|
|
});
|
|
const data = await res.json();
|
|
removeLoading();
|
|
if (data.results && data.results.length > 0) {
|
|
addLine(`🔍 Résultats KB pour "${term}":\n━━━━━━━━━━━━━━━━━━━━━━━━`, 'system');
|
|
data.results.forEach((r, i) => addLine(`${i + 1}. ${r.title}\n ${r.content.substring(0, 100)}...`, 'output'));
|
|
} else {
|
|
addLine(`Aucun résultat pour "${term}"`, 'system');
|
|
}
|
|
} catch (e) {
|
|
removeLoading();
|
|
addLine('Erreur recherche KB: ' + e.message, 'error');
|
|
}
|
|
}
|
|
|
|
async function sendToAI(message) {
|
|
addLoading();
|
|
const startTime = Date.now();
|
|
|
|
try {
|
|
const res = await fetch('/hamid-api.php', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
message: message,
|
|
provider: providerSelect.value,
|
|
session_id: sessionId
|
|
})
|
|
});
|
|
|
|
const data = await res.json();
|
|
removeLoading();
|
|
|
|
const latency = Date.now() - startTime;
|
|
document.getElementById('latency').textContent = latency + 'ms';
|
|
messageCount++;
|
|
document.getElementById('msgCount').textContent = messageCount;
|
|
|
|
if (data.error) {
|
|
addLine('❌ ' + data.error, 'error');
|
|
} else {
|
|
// Show thinking if available
|
|
if (data.thinking) {
|
|
addThinking(data.thinking);
|
|
}
|
|
|
|
let resp = data.response.replace(/<thinking>[\s\S]*?<\/thinking>/gi, "").trim(); addLine(resp);
|
|
addLine(`[${data.provider || providerSelect.value} | ${data.duration || latency}ms | KB:${data.kb_count || 0}]`, 'system');
|
|
|
|
if (data.generated_doc) {
|
|
addLine(`📄 Document généré: ${data.generated_doc.url}`, 'success');
|
|
}
|
|
}
|
|
} catch (e) {
|
|
removeLoading();
|
|
addLine('❌ Erreur: ' + e.message, 'error');
|
|
}
|
|
}
|
|
</script>
|
|
|
|
|
|
|
|
</body>
|
|
</html>
|