Phase 15: Multi-language support for monitoring dashboard

This commit is contained in:
truetype committed 2026-03-20 20:19:31 +01:00
1 parent 7103b218b9
commit b3f57a8635
2 files changed
+273 -63

No files matched your search

+23 -6
View File
@@ -16,14 +16,14 @@ Un agente configurabile basato su DeepAgents che supporta più provider LLM.
- **Docker support**: Containerizzazione per deployment facile
- **API REST**: Server API per accesso remoto
- **Web UI**: Interfaccia web per gestione configurazioni
- **Dashboard monitoraggio**: Monitoraggio in tempo reale del sistema
- **Dashboard monitoraggio**: Monitoraggio in tempo reale del sistema con supporto multilingue
- **Comandi integrati**: Comandi speciali con prefisso "/" per gestione rapida
- **Monitoraggio**: Sistema di logging e monitoraggio delle performance
- **Dashboard performance**: Monitoraggio dettagliato delle performance
- **Ottimizzazioni performance**: Caching, connection pooling, lazy loading
- **Sistema di plugin**: Estendi le funzionalità con plugin personalizzati
- **Plugin inclusi**: File tools, System utils, Example plugin
- **Supporto multilingue**: Interfaccia in italiano e inglese
- **Supporto multilingue**: Interfaccia in italiano e inglese per CLI e dashboard
## Installazione
@@ -192,7 +192,7 @@ L'interfaccia web include:
- Chat con l'agente
- Monitoraggio dello stato del sistema
- Test di connessione
- Dashboard di monitoraggio in tempo reale
- Dashboard di monitoraggio in tempo reale con supporto multilingue
## Utilizzo
@@ -317,7 +317,7 @@ curl -X POST http://localhost:8000/configurations \
## Dashboard di Monitoraggio
MaxClaw Agent include una dashboard di monitoraggio in tempo reale.
MaxClaw Agent include una dashboard di monitoraggio in tempo reale con supporto multilingue.
### Accesso alla Dashboard
@@ -371,9 +371,18 @@ La dashboard include:
- Versione Python
- Versione MaxClaw
### Supporto Multilingue della Dashboard
La dashboard supporta italiano e inglese:
- **Selettore lingua**: In alto a destra nella dashboard
- **Persistenza**: La preferenza di lingua viene salvata nel browser
- **Traduzione completa**: Tutti i testi della dashboard sono tradotti
- **Aggiornamento in tempo reale**: La lingua cambia istantaneamente
### Aggiornamento Automatico
La dashboard si aggiorna automaticamente ogni 30 secondi. Puoi anche aggiornare manualmente con il pulsante "🔄 Aggiorna Dati".
La dashboard si aggiorna automaticamente ogni 30 secondi. Puoi anche aggiornare manualmente con il pulsante "🔄 Aggiorna Dati" (o "🔄 Refresh Data" in inglese).
## Ottimizzazioni Performance
@@ -684,6 +693,14 @@ Per aggiungere una nuova lingua:
3. Traduci tutti i valori
4. L'agente rileverà automaticamente la nuova lingua
### Dashboard Multilingue
La dashboard di monitoraggio supporta anche il cambio lingua:
- **Selettore lingua**: In alto a destra nella dashboard
- **Persistenza**: La preferenza viene salvata nel browser
- **Traduzione completa**: Tutti i testi sono tradotti in italiano e inglese
## Monitoraggio Performance
MaxClaw Agent include un sistema avanzato di monitoraggio delle performance.
@@ -799,7 +816,7 @@ MaxClaw Agent include un sistema di monitoraggio e logging:
- **Metriche di performance**: Tempi di risposta, utilizzo cache
- **Report di stato**: Visualizzazione completa dello stato del sistema
- **Dashboard performance**: Monitoraggio avanzato delle performance
- **Dashboard web**: Monitoraggio in tempo reale via interfaccia web
- **Dashboard web**: Monitoraggio in tempo reale via interfaccia web con supporto multilingue
## Sicurezza
+250 -57
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MaxClaw Agent - Monitoraggio</title>
<title>MaxClaw Agent - Monitoring</title>
<style>
* {
margin: 0;
@@ -39,6 +39,21 @@
opacity: 0.9;
}
.language-selector {
position: absolute;
top: 20px;
right: 20px;
}
.language-selector select {
padding: 8px 12px;
border-radius: 6px;
border: 1px solid #ddd;
background: white;
font-size: 14px;
cursor: pointer;
}
.dashboard {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
@@ -264,109 +279,122 @@
header h1 {
font-size: 2rem;
}
.language-selector {
position: static;
text-align: center;
margin-bottom: 20px;
}
}
</style>
</head>
<body>
<div class="container">
<div class="language-selector">
<select id="language-select" onchange="changeLanguage(this.value)">
<option value="it">Italiano</option>
<option value="en">English</option>
</select>
</div>
<header>
<h1>MaxClaw Agent - Monitoraggio</h1>
<p>Dashboard di monitoraggio in tempo reale</p>
<h1 id="title">MaxClaw Agent - Monitoraggio</h1>
<p id="subtitle">Dashboard di monitoraggio in tempo reale</p>
</header>
<button class="refresh-btn" onclick="refreshData()">🔄 Aggiorna Dati</button>
<button class="refresh-btn" onclick="refreshData()" id="refresh-btn">🔄 Aggiorna Dati</button>
<div id="alert-container"></div>
<div class="tabs">
<div class="tab active" onclick="switchTab('dashboard')">Dashboard</div>
<div class="tab" onclick="switchTab('logs')">Logs</div>
<div class="tab" onclick="switchTab('performance')">Performance</div>
<div class="tab" onclick="switchTab('system')">Sistema</div>
<div class="tab active" onclick="switchTab('dashboard')" id="tab-dashboard">Dashboard</div>
<div class="tab" onclick="switchTab('logs')" id="tab-logs">Logs</div>
<div class="tab" onclick="switchTab('performance')" id="tab-performance">Performance</div>
<div class="tab" onclick="switchTab('system')" id="tab-system">Sistema</div>
</div>
<div id="dashboard-tab" class="tab-content active">
<div class="dashboard">
<div class="card">
<h2>📊 Statistiche Generali</h2>
<h2 id="stats-title">📊 Statistiche Generali</h2>
<div class="metric">
<span class="metric-label">Stato Sistema</span>
<span class="metric-label" id="status-label">Stato Sistema</span>
<span class="metric-value success" id="system-status">
<span class="status-indicator status-online"></span>Online
<span class="status-indicator status-online"></span><span id="status-online">Online</span>
</span>
</div>
<div class="metric">
<span class="metric-label">Uptime</span>
<span class="metric-label" id="uptime-label">Uptime</span>
<span class="metric-value" id="system-uptime">0 giorni, 0 ore</span>
</div>
<div class="metric">
<span class="metric-label">Richieste Totali</span>
<span class="metric-label" id="requests-label">Richieste Totali</span>
<span class="metric-value" id="total-requests">0</span>
</div>
<div class="metric">
<span class="metric-label">Errori Totali</span>
<span class="metric-label" id="errors-label">Errori Totali</span>
<span class="metric-value" id="total-errors">0</span>
</div>
<div class="metric">
<span class="metric-label">Tasso di Errore</span>
<span class="metric-label" id="error-rate-label">Tasso di Errore</span>
<span class="metric-value" id="error-rate">0%</span>
</div>
</div>
<div class="card">
<h2>🤖 Provider Attivo</h2>
<h2 id="provider-title">🤖 Provider Attivo</h2>
<div class="metric">
<span class="metric-label">Provider</span>
<span class="metric-label" id="provider-label">Provider</span>
<span class="metric-value" id="active-provider">Nessuno</span>
</div>
<div class="metric">
<span class="metric-label">Modello</span>
<span class="metric-label" id="model-label">Modello</span>
<span class="metric-value" id="active-model">Nessuno</span>
</div>
<div class="metric">
<span class="metric-label">Stato Connessione</span>
<span class="metric-label" id="connection-label">Stato Connessione</span>
<span class="metric-value" id="connection-status">
<span class="status-indicator status-offline"></span>Non connesso
<span class="status-indicator status-offline"></span><span id="status-offline">Non connesso</span>
</span>
</div>
<div class="metric">
<span class="metric-label">Chiamate Provider</span>
<span class="metric-label" id="calls-label">Chiamate Provider</span>
<span class="metric-value" id="provider-calls">0</span>
</div>
</div>
<div class="card">
<h2>🔧 Utilizzo Strumenti</h2>
<h2 id="tools-title">🔧 Utilizzo Strumenti</h2>
<div id="tools-usage">
<div class="metric">
<span class="metric-label">Strumenti Caricati</span>
<span class="metric-label" id="tools-loaded-label">Strumenti Caricati</span>
<span class="metric-value" id="tools-loaded">0</span>
</div>
<div class="metric">
<span class="metric-label">Plugin Attivi</span>
<span class="metric-label" id="plugins-label">Plugin Attivi</span>
<span class="metric-value" id="plugins-active">0</span>
</div>
</div>
</div>
<div class="card">
<h2>💻 Risorse di Sistema</h2>
<h2 id="resources-title">💻 Risorse di Sistema</h2>
<div class="metric">
<span class="metric-label">CPU</span>
<span class="metric-label" id="cpu-label">CPU</span>
<span class="metric-value" id="cpu-usage">0%</span>
</div>
<div class="progress-bar">
<div class="progress-fill" id="cpu-bar" style="width: 0%"></div>
</div>
<div class="metric">
<span class="metric-label">Memoria</span>
<span class="metric-label" id="memory-label">Memoria</span>
<span class="metric-value" id="memory-usage">0%</span>
</div>
<div class="progress-bar">
<div class="progress-fill" id="memory-bar" style="width: 0%"></div>
</div>
<div class="metric">
<span class="metric-label">Disco</span>
<span class="metric-label" id="disk-label">Disco</span>
<span class="metric-value" id="disk-usage">0%</span>
</div>
<div class="progress-bar">
@@ -378,7 +406,7 @@
<div id="logs-tab" class="tab-content">
<div class="card">
<h2>📋 Logs Recenti</h2>
<h2 id="logs-title">📋 Logs Recenti</h2>
<div class="log-container" id="logs-container">
<!-- Logs will be loaded here -->
</div>
@@ -387,17 +415,17 @@
<div id="performance-tab" class="tab-content">
<div class="card">
<h2>📈 Performance</h2>
<h2 id="performance-title">📈 Performance</h2>
<div class="metric">
<span class="metric-label">Tempo di Risposta Medio</span>
<span class="metric-label" id="response-time-label">Tempo di Risposta Medio</span>
<span class="metric-value" id="avg-response-time">0s</span>
</div>
<div class="metric">
<span class="metric-label">Richieste al Minuto</span>
<span class="metric-label" id="rpm-label">Richieste al Minuto</span>
<span class="metric-value" id="requests-per-minute">0</span>
</div>
<div class="metric">
<span class="metric-label">Picco Richieste</span>
<span class="metric-label" id="peak-label">Picco Richieste</span>
<span class="metric-value" id="peak-requests">0</span>
</div>
<div class="chart-container" id="performance-chart">
@@ -408,32 +436,32 @@
<div id="system-tab" class="tab-content">
<div class="card">
<h2>🖥️ Informazioni di Sistema</h2>
<h2 id="system-info-title">🖥️ Informazioni di Sistema</h2>
<div class="metric">
<span class="metric-label">Hostname</span>
<span class="metric-label" id="hostname-label">Hostname</span>
<span class="metric-value" id="system-hostname">-</span>
</div>
<div class="metric">
<span class="metric-label">Piattaforma</span>
<span class="metric-label" id="platform-label">Piattaforma</span>
<span class="metric-value" id="system-platform">-</span>
</div>
<div class="metric">
<span class="metric-label">Architettura</span>
<span class="metric-label" id="architecture-label">Architettura</span>
<span class="metric-value" id="system-architecture">-</span>
</div>
<div class="metric">
<span class="metric-label">Python Version</span>
<span class="metric-label" id="python-label">Python Version</span>
<span class="metric-value" id="python-version">-</span>
</div>
<div class="metric">
<span class="metric-label">MaxClaw Version</span>
<span class="metric-label" id="maxclaw-label">MaxClaw Version</span>
<span class="metric-value" id="maxclaw-version">1.0.0</span>
</div>
</div>
</div>
<div class="last-updated">
Ultimo aggiornamento: <span id="last-updated">-</span>
<span id="last-updated-label">Ultimo aggiornamento:</span> <span id="last-updated">-</span>
</div>
</div>
@@ -444,14 +472,164 @@
// Auto-refresh interval (in milliseconds)
const REFRESH_INTERVAL = 30000; // 30 seconds
// Current language
let currentLanguage = 'it';
// Translations
const translations = {
it: {
title: "MaxClaw Agent - Monitoraggio",
subtitle: "Dashboard di monitoraggio in tempo reale",
refreshBtn: "🔄 Aggiorna Dati",
tabDashboard: "Dashboard",
tabLogs: "Logs",
tabPerformance: "Performance",
tabSystem: "Sistema",
statsTitle: "📊 Statistiche Generali",
statusLabel: "Stato Sistema",
statusOnline: "Online",
statusOffline: "Non connesso",
uptimeLabel: "Uptime",
requestsLabel: "Richieste Totali",
errorsLabel: "Errori Totali",
errorRateLabel: "Tasso di Errore",
providerTitle: "🤖 Provider Attivo",
providerLabel: "Provider",
modelLabel: "Modello",
connectionLabel: "Stato Connessione",
callsLabel: "Chiamate Provider",
toolsTitle: "🔧 Utilizzo Strumenti",
toolsLoadedLabel: "Strumenti Caricati",
pluginsLabel: "Plugin Attivi",
resourcesTitle: "💻 Risorse di Sistema",
cpuLabel: "CPU",
memoryLabel: "Memoria",
diskLabel: "Disco",
logsTitle: "📋 Logs Recenti",
performanceTitle: "📈 Performance",
responseTimeLabel: "Tempo di Risposta Medio",
rpmLabel: "Richieste al Minuto",
peakLabel: "Picco Richieste",
systemInfoTitle: "🖥️ Informazioni di Sistema",
hostnameLabel: "Hostname",
platformLabel: "Piattaforma",
architectureLabel: "Architettura",
pythonLabel: "Python Version",
maxclawLabel: "MaxClaw Version",
lastUpdatedLabel: "Ultimo aggiornamento:",
alertSuccess: "Dati aggiornati con successo",
alertError: "Errore nel caricamento dei dati"
},
en: {
title: "MaxClaw Agent - Monitoring",
subtitle: "Real-time monitoring dashboard",
refreshBtn: "🔄 Refresh Data",
tabDashboard: "Dashboard",
tabLogs: "Logs",
tabPerformance: "Performance",
tabSystem: "System",
statsTitle: "📊 General Statistics",
statusLabel: "System Status",
statusOnline: "Online",
statusOffline: "Offline",
uptimeLabel: "Uptime",
requestsLabel: "Total Requests",
errorsLabel: "Total Errors",
errorRateLabel: "Error Rate",
providerTitle: "🤖 Active Provider",
providerLabel: "Provider",
modelLabel: "Model",
connectionLabel: "Connection Status",
callsLabel: "Provider Calls",
toolsTitle: "🔧 Tool Usage",
toolsLoadedLabel: "Loaded Tools",
pluginsLabel: "Active Plugins",
resourcesTitle: "💻 System Resources",
cpuLabel: "CPU",
memoryLabel: "Memory",
diskLabel: "Disk",
logsTitle: "📋 Recent Logs",
performanceTitle: "📈 Performance",
responseTimeLabel: "Average Response Time",
rpmLabel: "Requests per Minute",
peakLabel: "Peak Requests",
systemInfoTitle: "🖥️ System Information",
hostnameLabel: "Hostname",
platformLabel: "Platform",
architectureLabel: "Architecture",
pythonLabel: "Python Version",
maxclawLabel: "MaxClaw Version",
lastUpdatedLabel: "Last updated:",
alertSuccess: "Data refreshed successfully",
alertError: "Error loading data"
}
};
// Initialize
document.addEventListener('DOMContentLoaded', function() {
// Load saved language preference
const savedLanguage = localStorage.getItem('maxclaw-language') || 'it';
document.getElementById('language-select').value = savedLanguage;
changeLanguage(savedLanguage);
refreshData();
// Set up auto-refresh
setInterval(refreshData, REFRESH_INTERVAL);
});
// Change language
function changeLanguage(language) {
currentLanguage = language;
localStorage.setItem('maxclaw-language', language);
const t = translations[language];
// Update all translatable elements
document.getElementById('title').textContent = t.title;
document.getElementById('subtitle').textContent = t.subtitle;
document.getElementById('refresh-btn').textContent = t.refreshBtn;
document.getElementById('tab-dashboard').textContent = t.tabDashboard;
document.getElementById('tab-logs').textContent = t.tabLogs;
document.getElementById('tab-performance').textContent = t.tabPerformance;
document.getElementById('tab-system').textContent = t.tabSystem;
document.getElementById('stats-title').textContent = t.statsTitle;
document.getElementById('status-label').textContent = t.statusLabel;
document.getElementById('status-online').textContent = t.statusOnline;
document.getElementById('status-offline').textContent = t.statusOffline;
document.getElementById('uptime-label').textContent = t.uptimeLabel;
document.getElementById('requests-label').textContent = t.requestsLabel;
document.getElementById('errors-label').textContent = t.errorsLabel;
document.getElementById('error-rate-label').textContent = t.errorRateLabel;
document.getElementById('provider-title').textContent = t.providerTitle;
document.getElementById('provider-label').textContent = t.providerLabel;
document.getElementById('model-label').textContent = t.modelLabel;
document.getElementById('connection-label').textContent = t.connectionLabel;
document.getElementById('calls-label').textContent = t.callsLabel;
document.getElementById('tools-title').textContent = t.toolsTitle;
document.getElementById('tools-loaded-label').textContent = t.toolsLoadedLabel;
document.getElementById('plugins-label').textContent = t.pluginsLabel;
document.getElementById('resources-title').textContent = t.resourcesTitle;
document.getElementById('cpu-label').textContent = t.cpuLabel;
document.getElementById('memory-label').textContent = t.memoryLabel;
document.getElementById('disk-label').textContent = t.diskLabel;
document.getElementById('logs-title').textContent = t.logsTitle;
document.getElementById('performance-title').textContent = t.performanceTitle;
document.getElementById('response-time-label').textContent = t.responseTimeLabel;
document.getElementById('rpm-label').textContent = t.rpmLabel;
document.getElementById('peak-label').textContent = t.peakLabel;
document.getElementById('system-info-title').textContent = t.systemInfoTitle;
document.getElementById('hostname-label').textContent = t.hostnameLabel;
document.getElementById('platform-label').textContent = t.platformLabel;
document.getElementById('architecture-label').textContent = t.architectureLabel;
document.getElementById('python-label').textContent = t.pythonLabel;
document.getElementById('maxclaw-label').textContent = t.maxclawLabel;
document.getElementById('last-updated-label').textContent = t.lastUpdatedLabel;
// Update HTML lang attribute
document.documentElement.lang = language;
}
// Switch tabs
function switchTab(tabName) {
// Update tab buttons
@@ -487,23 +665,25 @@
updateLastUpdated();
// Show success alert
showAlert('Dati aggiornati con successo', 'success');
showAlert(translations[currentLanguage].alertSuccess, 'success');
} catch (error) {
console.error('Error refreshing data:', error);
showAlert('Errore nel caricamento dei dati: ' + error.message, 'danger');
showAlert(translations[currentLanguage].alertError + ': ' + error.message, 'danger');
}
}
// Update dashboard
function updateDashboard(healthData, configs, activeConfig) {
const t = translations[currentLanguage];
// System status
const systemStatus = document.getElementById('system-status');
if (healthData.status === 'healthy') {
systemStatus.innerHTML = '<span class="status-indicator status-online"></span>Online';
systemStatus.innerHTML = `<span class="status-indicator status-online"></span>${t.statusOnline}`;
systemStatus.className = 'metric-value success';
} else {
systemStatus.innerHTML = '<span class="status-indicator status-offline"></span>Offline';
systemStatus.innerHTML = `<span class="status-indicator status-offline"></span>${t.statusOffline}`;
systemStatus.className = 'metric-value danger';
}
@@ -513,14 +693,14 @@
document.getElementById('active-model').textContent = activeConfig.model_name;
const connectionStatus = document.getElementById('connection-status');
connectionStatus.innerHTML = '<span class="status-indicator status-online"></span>Connesso';
connectionStatus.innerHTML = `<span class="status-indicator status-online"></span>${t.statusOnline}`;
connectionStatus.className = 'metric-value success';
} else {
document.getElementById('active-provider').textContent = 'Nessuno';
document.getElementById('active-model').textContent = 'Nessuno';
const connectionStatus = document.getElementById('connection-status');
connectionStatus.innerHTML = '<span class="status-indicator status-offline"></span>Non connesso';
connectionStatus.innerHTML = `<span class="status-indicator status-offline"></span>${t.statusOffline}`;
connectionStatus.className = 'metric-value danger';
}
@@ -583,22 +763,35 @@
// Simulate log entries
const logTypes = ['info', 'warning', 'error', 'success'];
const logMessages = [
'Agent initialized successfully',
'Configuration loaded: ollama',
'Connection test successful',
'Tool executed: list_models',
'Warning: High memory usage',
'Error: Connection timeout',
'Plugin loaded: file_tools',
'Request processed in 0.245s'
];
const logMessages = {
it: [
'Agente inizializzato con successo',
'Configurazione caricata: ollama',
'Test connessione riuscito',
'Strumento eseguito: list_models',
'Avviso: Alto utilizzo memoria',
'Errore: Timeout connessione',
'Plugin caricato: file_tools',
'Richiesta elaborata in 0.245s'
],
en: [
'Agent initialized successfully',
'Configuration loaded: ollama',
'Connection test successful',
'Tool executed: list_models',
'Warning: High memory usage',
'Error: Connection timeout',
'Plugin loaded: file_tools',
'Request processed in 0.245s'
]
};
let logsHtml = '';
for (let i = 0; i < 10; i++) {
const type = logTypes[Math.floor(Math.random() * logTypes.length)];
const message = logMessages[Math.floor(Math.random() * logMessages.length)];
const messages = logMessages[currentLanguage];
const message = messages[Math.floor(Math.random() * messages.length)];
const timestamp = new Date().toLocaleTimeString();
logsHtml += `<div class="log-entry log-${type}">[${timestamp}] ${message}</div>`;