feat: reorganize tabs + add Last Prompt CC/Fallback toggle

- Split Status tab: moved DM management to new dedicated 📱 DM Management tab
- Added Last Prompt source toggle (Cheshire Cat / Bot Fallback) with
  localStorage persistence, CC as default
- Backend: added LAST_CAT_INTERACTION global, /prompt/cat API endpoint
- Bot tracks Cat interactions (prompt, response, user, mood, timestamp)
- Auto-load data on tab switch (Status loads prompt, DM tab loads users)
This commit is contained in:
2026-03-01 00:26:22 +02:00
parent 5bdd907730
commit 1037d13b0a
4 changed files with 125 additions and 15 deletions

View File

@@ -433,6 +433,20 @@
color: #fff;
border-bottom-color: #4CAF50;
}
/* Prompt source toggle buttons */
.prompt-source-btn {
background: #333;
color: #aaa;
}
.prompt-source-btn.active {
background: #4CAF50;
color: #fff;
}
.prompt-source-btn:hover:not(.active) {
background: #444;
color: #ddd;
}
.tab-content {
display: none;
@@ -661,6 +675,7 @@
<button class="tab-button active" data-tab="tab1" onclick="switchTab('tab1')">Server Management</button>
<button class="tab-button" data-tab="tab2" onclick="switchTab('tab2')">Actions</button>
<button class="tab-button" data-tab="tab3" onclick="switchTab('tab3')">Status</button>
<button class="tab-button" data-tab="tab10" onclick="switchTab('tab10')">📱 DM Management</button>
<button class="tab-button" data-tab="tab4" onclick="switchTab('tab4')">⚙️ LLM Settings</button>
<button class="tab-button" data-tab="tab5" onclick="switchTab('tab5')">🎨 Image Generation</button>
<button class="tab-button" data-tab="tab6" onclick="switchTab('tab6')">📊 Autonomous Stats</button>
@@ -1149,13 +1164,35 @@
<!-- Status Tab Content -->
<div id="tab3" class="tab-content">
<div class="section">
<h3>Status</h3>
<div id="status"></div>
</div>
<div class="section">
<h3>Status</h3>
<div id="status"></div>
</div>
<div class="section">
<h3>📱 DM Logs</h3>
<h3>Last Prompt</h3>
<div style="margin-bottom: 0.75rem; display: flex; align-items: center; gap: 0.75rem;">
<label style="font-size: 0.9rem; color: #aaa;">Source:</label>
<div style="display: inline-flex; border-radius: 6px; overflow: hidden; border: 1px solid #444;">
<button id="prompt-src-cat" class="prompt-source-btn active" onclick="switchPromptSource('cat')"
style="padding: 0.4rem 1rem; border: none; cursor: pointer; font-size: 0.85rem; transition: all 0.2s;">
🐱 Cheshire Cat
</button>
<button id="prompt-src-fallback" class="prompt-source-btn" onclick="switchPromptSource('fallback')"
style="padding: 0.4rem 1rem; border: none; cursor: pointer; font-size: 0.85rem; transition: all 0.2s;">
🤖 Bot Fallback
</button>
</div>
</div>
<div id="prompt-cat-info" style="margin-bottom: 0.5rem; font-size: 0.85rem; color: #aaa;"></div>
<pre id="last-prompt" style="white-space: pre-wrap; word-break: break-word;"></pre>
</div>
</div>
<!-- DM Management Tab Content -->
<div id="tab10" class="tab-content">
<div class="section">
<h3>📱 DM Management</h3>
<div style="margin-bottom: 1rem;">
<button onclick="loadDMUsers()">🔄 Refresh DM Users</button>
<button onclick="exportAllDMs()">📤 Export All DMs</button>
@@ -1179,11 +1216,6 @@
<div id="blocked-users-list"></div>
</div>
</div>
<div class="section">
<h3>Last Prompt</h3>
<pre id="last-prompt"></pre>
</div>
</div>
<!-- LLM Settings Tab Content -->
@@ -1842,10 +1874,18 @@ function switchTab(tabId) {
console.log('🔄 Refreshing figurine subscribers for Server Management tab');
refreshFigurineSubscribers();
}
if (tabId === 'tab3') {
loadStatus();
loadLastPrompt();
}
if (tabId === 'tab9') {
console.log('🧠 Refreshing memory stats for Memories tab');
refreshMemoryStats();
}
if (tabId === 'tab10') {
console.log('📱 Loading DM users for DM Management tab');
loadDMUsers();
}
}
// ============================================================================
@@ -1945,6 +1985,7 @@ document.addEventListener('DOMContentLoaded', function() {
initLogsScrollDetection();
initChatImagePreview();
initModalAccessibility();
initPromptSourceToggle();
// Load initial data
loadStatus();
@@ -3948,14 +3989,43 @@ async function loadStatus() {
}
async function loadLastPrompt() {
const source = localStorage.getItem('miku-prompt-source') || 'cat';
const promptEl = document.getElementById('last-prompt');
const infoEl = document.getElementById('prompt-cat-info');
try {
const result = await apiCall('/prompt');
document.getElementById('last-prompt').textContent = result.prompt;
if (source === 'cat') {
const result = await apiCall('/prompt/cat');
if (result.timestamp) {
infoEl.innerHTML = `<strong>User:</strong> ${escapeHtml(result.user || '?')} &nbsp;|&nbsp; <strong>Mood:</strong> ${escapeHtml(result.mood || '?')} &nbsp;|&nbsp; <strong>Time:</strong> ${new Date(result.timestamp).toLocaleString()}`;
promptEl.textContent = `[User message → Cat]\n${result.prompt}\n\n[Cat response]\n${result.response}`;
} else {
infoEl.textContent = '';
promptEl.textContent = result.prompt || 'No Cheshire Cat interaction yet.';
}
} else {
infoEl.textContent = '';
const result = await apiCall('/prompt');
promptEl.textContent = result.prompt;
}
} catch (error) {
console.error('Failed to load last prompt:', error);
}
}
function switchPromptSource(source) {
localStorage.setItem('miku-prompt-source', source);
document.querySelectorAll('.prompt-source-btn').forEach(btn => btn.classList.remove('active'));
document.getElementById(`prompt-src-${source}`).classList.add('active');
loadLastPrompt();
}
function initPromptSourceToggle() {
const saved = localStorage.getItem('miku-prompt-source') || 'cat';
document.querySelectorAll('.prompt-source-btn').forEach(btn => btn.classList.remove('active'));
document.getElementById(`prompt-src-${saved}`).classList.add('active');
}
// Log auto-scroll state
let logsAutoScroll = true;