// ─── Supervisor View ─── import { api } from '../api.js'; export class SupervisorView { constructor(container, setStatus) { this.container = container; this.setStatus = setStatus; this.currentSubTab = 'analysis'; this.profiles = []; this.signals = []; this.selectedSignal = null; } async render() { this.container.innerHTML = `
`; const subtabs = this.container.querySelectorAll('[data-subtab]'); subtabs.forEach(tab => { tab.addEventListener('click', () => { subtabs.forEach(t => t.classList.remove('active')); tab.classList.add('active'); this.currentSubTab = tab.getAttribute('data-subtab'); this.renderSubTab(); }); }); await this.loadProfiles(); await this.renderSubTab(); } async loadProfiles() { try { const data = await api.get('/api/modules/supervisor/profiles'); if (Array.isArray(data)) { this.profiles = data; } } catch (e) { console.warn('Konnte Supervisor-Profile nicht laden:', e); } } async renderSubTab() { const sub = document.getElementById('sup-subcontent'); if (!sub) return; if (this.currentSubTab === 'analysis') { sub.innerHTML = `
Profil:
Wählen Sie ein Profil, geben Sie eine Frage ein und klicken Sie auf 'Fragen'.
`; document.getElementById('sup-ask-btn').addEventListener('click', () => this.ask()); document.getElementById('sup-question-input').addEventListener('keydown', (e) => { if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) { e.preventDefault(); this.ask(); } }); } else if (this.currentSubTab === 'dossier') { sub.innerHTML = `
Zeit Symbol Modul Entscheidung
Signale laden …
Dossier-Details
Signal in der linken Tabelle auswählen.
`; document.getElementById('sup-load-signals-btn').addEventListener('click', () => this.loadSignals()); await this.loadSignals(); } else if (this.currentSubTab === 'reports') { sub.innerHTML = `
Erstellt Profil Modell Frage Tools Tokens
Lade Berichte …
`; document.getElementById('sup-load-reports-btn').addEventListener('click', () => this.loadReports()); await this.loadReports(); } else if (this.currentSubTab === 'info') { sub.innerHTML = `

Supervisor Modul-Hinweise

Lade Modul-Informationen …
`; await this.loadInfo(); } } async ask() { const qEl = document.getElementById('sup-question-input'); const question = qEl?.value?.trim(); if (!question) { alert('Bitte eine Frage eingeben.'); return; } const pEl = document.getElementById('sup-profile-select'); const profile = pEl?.value; const btn = document.getElementById('sup-ask-btn'); const ansEl = document.getElementById('sup-answer-container'); const statusEl = document.getElementById('sup-ask-status'); btn.disabled = true; btn.textContent = '⏳ Analysiere …'; if (statusEl) statusEl.textContent = 'Agent denkt nach …'; ansEl.textContent = 'Agent führt Tool-Aufrufe und Analysen durch … Bitte warten.'; try { const res = await api.post('/api/modules/supervisor/ask', { question, profile }); if (res && res.success) { let output = res.answer || '(Keine Antwort erhalten)'; if (res.toolCalls && res.toolCalls.length > 0) { output += '\n\n── Ausgeführte Tool-Calls ──\n' + res.toolCalls.map(tc => `• ${tc.tool}: ${JSON.stringify(tc.arguments)}`).join('\n'); } ansEl.textContent = output; if (statusEl) statusEl.textContent = `Fertig (${res.toolCallCount || 0} Tools genutzt).`; } else { ansEl.textContent = `Fehler: ${res?.message || 'Unbekannter Fehler'}`; } } catch (e) { ansEl.textContent = `Fehler bei der Abfrage: ${e.message}`; } finally { btn.disabled = false; btn.textContent = '⚡ Fragen'; } } async loadSignals() { this.setStatus('Lade Signale …'); try { const signals = await api.get('/api/modules/supervisor/signals?limit=100'); this.signals = Array.isArray(signals) ? signals : []; const tbody = document.getElementById('sup-signals-tbody'); if (!tbody) return; if (this.signals.length === 0) { tbody.innerHTML = `Keine Signale gefunden.`; } else { tbody.innerHTML = this.signals.map((s, idx) => ` ${s.firstSeen ? s.firstSeen.substring(5, 16) : '–'} ${s.symbol || '–'} ${s.module || '–'} ${s.lastDecision || '–'} `).join(''); tbody.querySelectorAll('tr').forEach(tr => { tr.addEventListener('click', () => { const idx = parseInt(tr.getAttribute('data-idx'), 10); this.selectSignal(this.signals[idx]); }); }); } this.setStatus(`Signale geladen (${this.signals.length}).`); } catch (e) { this.setStatus(`Fehler: ${e.message}`); } } async selectSignal(s) { this.selectedSignal = s; const headerEl = document.getElementById('sup-dossier-header'); const bodyEl = document.getElementById('sup-dossier-body'); if (!bodyEl) return; if (headerEl) headerEl.textContent = `Dossier: ${s.symbol} (${s.signalId})`; bodyEl.textContent = 'Lade Dossier …'; try { const data = await api.get(`/api/modules/supervisor/dossier/${encodeURIComponent(s.signalId)}`); if (data && data.markdown) { bodyEl.textContent = data.markdown; } else { bodyEl.textContent = 'Kein Dossier für dieses Signal verfügbar.'; } } catch (e) { bodyEl.textContent = `Fehler beim Laden des Dossiers: ${e.message}`; } } async loadReports() { this.setStatus('Lade Berichte …'); try { const reports = await api.get('/api/modules/supervisor/reports?limit=100'); const tbody = document.getElementById('sup-reports-tbody'); if (!tbody) return; if (!Array.isArray(reports) || reports.length === 0) { tbody.innerHTML = `Keine Berichte vorhanden.`; } else { tbody.innerHTML = reports.map(r => ` ${r.createdAt} ${r.profile} ${r.model} ${r.question} ${r.toolCallCount} ${r.tokens} `).join(''); } this.setStatus(`Berichte geladen (${reports ? reports.length : 0}).`); } catch (e) { this.setStatus(`Fehler: ${e.message}`); } } async loadInfo() { try { const info = await api.get('/api/modules/supervisor/info'); const el = document.getElementById('sup-info-content'); if (!el || !info) return; el.innerHTML = `
OpenRouter API-Key: ${info.openRouterKeyConfigured ? '✅ Konfiguriert' : '⚠️ Nicht gesetzt (in settings.json oder OPENROUTER_API_KEY hinterlegen)'}

Zeitzone: ${info.timeZone || '–'}

Beschreibung: ${info.description || '–'}

`; } catch (e) { console.error(e); } } }