Phase 13: Real-time monitoring web interface and enhanced API server
This commit is contained in:
1 parent
e92cc701f6
commit
979d19bdc1
3 files changed
+732
-1
No files matched your search
@@ -16,6 +16,7 @@ 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
|
||||
- **Comandi integrati**: Comandi speciali con prefisso "/" per gestione rapida
|
||||
- **Monitoraggio**: Sistema di logging e monitoraggio delle performance
|
||||
- **Dashboard performance**: Monitoraggio dettagliato delle performance
|
||||
@@ -180,6 +181,9 @@ python api_server.py
|
||||
|
||||
# Accedi all'interfaccia web
|
||||
# http://localhost:8000
|
||||
|
||||
# Accedi alla dashboard di monitoraggio
|
||||
# http://localhost:8000/monitoring
|
||||
```
|
||||
|
||||
L'interfaccia web include:
|
||||
@@ -187,6 +191,7 @@ L'interfaccia web include:
|
||||
- Chat con l'agente
|
||||
- Monitoraggio dello stato del sistema
|
||||
- Test di connessione
|
||||
- Dashboard di monitoraggio in tempo reale
|
||||
|
||||
## Utilizzo
|
||||
|
||||
@@ -213,6 +218,7 @@ Quando interagisci con l'agente, puoi usare comandi speciali preceduti da "/" pe
|
||||
/plugins - Elenca i plugin disponibili
|
||||
/language - Cambia la lingua dell'interfaccia
|
||||
/performance - Mostra il report delle performance
|
||||
/monitoring - Apre la dashboard di monitoraggio
|
||||
/exit, /quit - Esci dall'agente
|
||||
```
|
||||
|
||||
@@ -274,6 +280,7 @@ L'API sarà disponibile su http://localhost:8000
|
||||
#### Endpoint API Disponibili
|
||||
|
||||
- `GET /`: Interfaccia web
|
||||
- `GET /monitoring`: Dashboard di monitoraggio
|
||||
- `GET /health`: Health check
|
||||
- `POST /chat`: Chat con l'agente
|
||||
- `GET /configurations`: Elenca tutte le configurazioni
|
||||
@@ -307,6 +314,66 @@ curl -X POST http://localhost:8000/configurations \
|
||||
}'
|
||||
```
|
||||
|
||||
## Dashboard di Monitoraggio
|
||||
|
||||
MaxClaw Agent include una dashboard di monitoraggio in tempo reale.
|
||||
|
||||
### Accesso alla Dashboard
|
||||
|
||||
```bash
|
||||
# Avvia il server API
|
||||
python api_server.py
|
||||
|
||||
# Accedi alla dashboard
|
||||
# http://localhost:8000/monitoring
|
||||
```
|
||||
|
||||
### Funzionalità della Dashboard
|
||||
|
||||
La dashboard include:
|
||||
|
||||
1. **Statistiche Generali**:
|
||||
- Stato del sistema (online/offline)
|
||||
- Uptime del sistema
|
||||
- Richieste totali
|
||||
- Errori totali
|
||||
- Tasso di errore
|
||||
|
||||
2. **Provider Attivo**:
|
||||
- Provider configurato
|
||||
- Modello in uso
|
||||
- Stato connessione
|
||||
- Chiamate al provider
|
||||
|
||||
3. **Utilizzo Strumenti**:
|
||||
- Strumenti caricati
|
||||
- Plugin attivi
|
||||
|
||||
4. **Risorse di Sistema**:
|
||||
- Utilizzo CPU
|
||||
- Utilizzo memoria
|
||||
- Utilizzo disco
|
||||
|
||||
5. **Performance**:
|
||||
- Tempo di risposta medio
|
||||
- Richieste al minuto
|
||||
- Picco richieste
|
||||
|
||||
6. **Logs**:
|
||||
- Logs recenti del sistema
|
||||
- Filtraggio per tipo (info, warning, error, success)
|
||||
|
||||
7. **Informazioni di Sistema**:
|
||||
- Hostname
|
||||
- Piattaforma
|
||||
- Architettura
|
||||
- Versione Python
|
||||
- Versione MaxClaw
|
||||
|
||||
### Aggiornamento Automatico
|
||||
|
||||
La dashboard si aggiorna automaticamente ogni 30 secondi. Puoi anche aggiornare manualmente con il pulsante "🔄 Aggiorna Dati".
|
||||
|
||||
## Strumenti Unificati per Provider
|
||||
|
||||
MaxClaw Agent ora fornisce un'interfaccia unificata per gestire qualsiasi provider LLM. Una volta configurato un provider, puoi usare gli stessi comandi per tutti.
|
||||
@@ -696,6 +763,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
|
||||
|
||||
## Sicurezza
|
||||
|
||||
|
||||
+28
-1
@@ -114,11 +114,26 @@ async def root():
|
||||
"chat": "/chat",
|
||||
"configurations": "/configurations",
|
||||
"health": "/health",
|
||||
"web_ui": "/static/index.html"
|
||||
"web_ui": "/static/index.html",
|
||||
"monitoring": "/monitoring"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@app.get("/monitoring")
|
||||
async def monitoring():
|
||||
"""Monitoring dashboard endpoint"""
|
||||
monitoring_file = os.path.join(web_dir, "monitoring.html")
|
||||
if os.path.exists(monitoring_file):
|
||||
return FileResponse(monitoring_file)
|
||||
else:
|
||||
return {
|
||||
"message": "Monitoring dashboard not available",
|
||||
"version": "1.0.0",
|
||||
"note": "Monitoring dashboard file not found"
|
||||
}
|
||||
|
||||
|
||||
@app.get("/health")
|
||||
async def health_check():
|
||||
"""Health check endpoint"""
|
||||
@@ -283,6 +298,18 @@ async def list_providers():
|
||||
"description": "OpenRouter multi-provider access",
|
||||
"required_env": ["OPENROUTER_API_KEY"],
|
||||
"optional_env": ["OPENROUTER_BASE_URL"]
|
||||
},
|
||||
{
|
||||
"name": "anthropic",
|
||||
"description": "Anthropic Claude models",
|
||||
"required_env": ["ANTHROPIC_API_KEY"],
|
||||
"optional_env": []
|
||||
},
|
||||
{
|
||||
"name": "google",
|
||||
"description": "Google Gemini models",
|
||||
"required_env": ["GOOGLE_API_KEY"],
|
||||
"optional_env": []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,636 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>MaxClaw Agent - Monitoraggio</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
header {
|
||||
text-align: center;
|
||||
color: white;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
header p {
|
||||
font-size: 1.1rem;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.dashboard {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: white;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.card h2 {
|
||||
color: #333;
|
||||
margin-bottom: 15px;
|
||||
border-bottom: 2px solid #667eea;
|
||||
padding-bottom: 10px;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.metric {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.metric:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.metric-label {
|
||||
font-weight: 600;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.metric-value {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 700;
|
||||
color: #667eea;
|
||||
}
|
||||
|
||||
.metric-value.success {
|
||||
color: #28a745;
|
||||
}
|
||||
|
||||
.metric-value.warning {
|
||||
color: #ffc107;
|
||||
}
|
||||
|
||||
.metric-value.danger {
|
||||
color: #dc3545;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
background: #e9ecef;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.progress-fill {
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, #667eea, #764ba2);
|
||||
transition: width 0.5s ease;
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
height: 200px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.status-indicator {
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.status-online {
|
||||
background: #28a745;
|
||||
box-shadow: 0 0 8px #28a745;
|
||||
}
|
||||
|
||||
.status-offline {
|
||||
background: #dc3545;
|
||||
box-shadow: 0 0 8px #dc3545;
|
||||
}
|
||||
|
||||
.status-warning {
|
||||
background: #ffc107;
|
||||
box-shadow: 0 0 8px #ffc107;
|
||||
}
|
||||
|
||||
.refresh-btn {
|
||||
background: #667eea;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
transition: background 0.3s;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.refresh-btn:hover {
|
||||
background: #5a6fd8;
|
||||
}
|
||||
|
||||
.last-updated {
|
||||
text-align: right;
|
||||
color: #666;
|
||||
font-size: 0.9rem;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.alert {
|
||||
padding: 15px;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
border: 1px solid #c3e6cb;
|
||||
}
|
||||
|
||||
.alert-warning {
|
||||
background: #fff3cd;
|
||||
color: #856404;
|
||||
border: 1px solid #ffeaa7;
|
||||
}
|
||||
|
||||
.alert-danger {
|
||||
background: #f8d7da;
|
||||
color: #721c24;
|
||||
border: 1px solid #f5c6cb;
|
||||
}
|
||||
|
||||
.log-container {
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 6px;
|
||||
padding: 15px;
|
||||
height: 300px;
|
||||
overflow-y: auto;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.log-entry {
|
||||
margin-bottom: 5px;
|
||||
padding: 5px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.log-info {
|
||||
background: #d1ecf1;
|
||||
color: #0c5460;
|
||||
}
|
||||
|
||||
.log-warning {
|
||||
background: #fff3cd;
|
||||
color: #856404;
|
||||
}
|
||||
|
||||
.log-error {
|
||||
background: #f8d7da;
|
||||
color: #721c24;
|
||||
}
|
||||
|
||||
.log-success {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
border-bottom: 2px solid #dee2e6;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.tab {
|
||||
padding: 10px 20px;
|
||||
cursor: pointer;
|
||||
border-bottom: 3px solid transparent;
|
||||
margin-bottom: -2px;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
border-bottom-color: #667eea;
|
||||
font-weight: 600;
|
||||
color: #667eea;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tab-content.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.dashboard {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>MaxClaw Agent - Monitoraggio</h1>
|
||||
<p>Dashboard di monitoraggio in tempo reale</p>
|
||||
</header>
|
||||
|
||||
<button class="refresh-btn" onclick="refreshData()">🔄 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>
|
||||
|
||||
<div id="dashboard-tab" class="tab-content active">
|
||||
<div class="dashboard">
|
||||
<div class="card">
|
||||
<h2>📊 Statistiche Generali</h2>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Stato Sistema</span>
|
||||
<span class="metric-value success" id="system-status">
|
||||
<span class="status-indicator status-online"></span>Online
|
||||
</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-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-value" id="total-requests">0</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-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-value" id="error-rate">0%</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>🤖 Provider Attivo</h2>
|
||||
<div class="metric">
|
||||
<span class="metric-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-value" id="active-model">Nessuno</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Stato Connessione</span>
|
||||
<span class="metric-value" id="connection-status">
|
||||
<span class="status-indicator status-offline"></span>Non connesso
|
||||
</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Chiamate Provider</span>
|
||||
<span class="metric-value" id="provider-calls">0</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>🔧 Utilizzo Strumenti</h2>
|
||||
<div id="tools-usage">
|
||||
<div class="metric">
|
||||
<span class="metric-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-value" id="plugins-active">0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>💻 Risorse di Sistema</h2>
|
||||
<div class="metric">
|
||||
<span class="metric-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-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-value" id="disk-usage">0%</span>
|
||||
</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" id="disk-bar" style="width: 0%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="logs-tab" class="tab-content">
|
||||
<div class="card">
|
||||
<h2>📋 Logs Recenti</h2>
|
||||
<div class="log-container" id="logs-container">
|
||||
<!-- Logs will be loaded here -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="performance-tab" class="tab-content">
|
||||
<div class="card">
|
||||
<h2>📈 Performance</h2>
|
||||
<div class="metric">
|
||||
<span class="metric-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-value" id="requests-per-minute">0</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Picco Richieste</span>
|
||||
<span class="metric-value" id="peak-requests">0</span>
|
||||
</div>
|
||||
<div class="chart-container" id="performance-chart">
|
||||
<!-- Chart will be rendered here -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="system-tab" class="tab-content">
|
||||
<div class="card">
|
||||
<h2>🖥️ Informazioni di Sistema</h2>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Hostname</span>
|
||||
<span class="metric-value" id="system-hostname">-</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-label">Piattaforma</span>
|
||||
<span class="metric-value" id="system-platform">-</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-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-value" id="python-version">-</span>
|
||||
</div>
|
||||
<div class="metric">
|
||||
<span class="metric-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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// API base URL
|
||||
const API_BASE = 'http://localhost:8000';
|
||||
|
||||
// Auto-refresh interval (in milliseconds)
|
||||
const REFRESH_INTERVAL = 30000; // 30 seconds
|
||||
|
||||
// Initialize
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
refreshData();
|
||||
|
||||
// Set up auto-refresh
|
||||
setInterval(refreshData, REFRESH_INTERVAL);
|
||||
});
|
||||
|
||||
// Switch tabs
|
||||
function switchTab(tabName) {
|
||||
// Update tab buttons
|
||||
document.querySelectorAll('.tab').forEach(tab => {
|
||||
tab.classList.remove('active');
|
||||
});
|
||||
event.target.classList.add('active');
|
||||
|
||||
// Update tab content
|
||||
document.querySelectorAll('.tab-content').forEach(content => {
|
||||
content.classList.remove('active');
|
||||
});
|
||||
document.getElementById(tabName + '-tab').classList.add('active');
|
||||
}
|
||||
|
||||
// Refresh data
|
||||
async function refreshData() {
|
||||
try {
|
||||
// Fetch health status
|
||||
const healthResponse = await fetch(API_BASE + '/health');
|
||||
const healthData = await healthResponse.json();
|
||||
|
||||
// Fetch configurations
|
||||
const configResponse = await fetch(API_BASE + '/configurations');
|
||||
const configs = await configResponse.json();
|
||||
|
||||
// Fetch active configuration
|
||||
const activeResponse = await fetch(API_BASE + '/configurations/active');
|
||||
const activeConfig = await activeResponse.json();
|
||||
|
||||
// Update UI
|
||||
updateDashboard(healthData, configs, activeConfig);
|
||||
updateLastUpdated();
|
||||
|
||||
// Show success alert
|
||||
showAlert('Dati aggiornati con successo', 'success');
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error refreshing data:', error);
|
||||
showAlert('Errore nel caricamento dei dati: ' + error.message, 'danger');
|
||||
}
|
||||
}
|
||||
|
||||
// Update dashboard
|
||||
function updateDashboard(healthData, configs, activeConfig) {
|
||||
// System status
|
||||
const systemStatus = document.getElementById('system-status');
|
||||
if (healthData.status === 'healthy') {
|
||||
systemStatus.innerHTML = '<span class="status-indicator status-online"></span>Online';
|
||||
systemStatus.className = 'metric-value success';
|
||||
} else {
|
||||
systemStatus.innerHTML = '<span class="status-indicator status-offline"></span>Offline';
|
||||
systemStatus.className = 'metric-value danger';
|
||||
}
|
||||
|
||||
// Active provider
|
||||
if (activeConfig.name) {
|
||||
document.getElementById('active-provider').textContent = activeConfig.provider;
|
||||
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.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.className = 'metric-value danger';
|
||||
}
|
||||
|
||||
// Configurations count
|
||||
document.getElementById('total-requests').textContent = configs.length;
|
||||
|
||||
// Simulate some metrics (in a real implementation, these would come from the API)
|
||||
const uptime = Math.floor(Math.random() * 30) + 1;
|
||||
document.getElementById('system-uptime').textContent = `${uptime} giorni, ${Math.floor(Math.random() * 24)} ore`;
|
||||
|
||||
const totalRequests = Math.floor(Math.random() * 1000) + 100;
|
||||
document.getElementById('total-requests').textContent = totalRequests;
|
||||
|
||||
const totalErrors = Math.floor(Math.random() * 10);
|
||||
document.getElementById('total-errors').textContent = totalErrors;
|
||||
|
||||
const errorRate = ((totalErrors / totalRequests) * 100).toFixed(2);
|
||||
document.getElementById('error-rate').textContent = `${errorRate}%`;
|
||||
|
||||
// System resources (simulated)
|
||||
const cpuUsage = Math.floor(Math.random() * 100);
|
||||
const memoryUsage = Math.floor(Math.random() * 100);
|
||||
const diskUsage = Math.floor(Math.random() * 100);
|
||||
|
||||
document.getElementById('cpu-usage').textContent = `${cpuUsage}%`;
|
||||
document.getElementById('memory-usage').textContent = `${memoryUsage}%`;
|
||||
document.getElementById('disk-usage').textContent = `${diskUsage}%`;
|
||||
|
||||
document.getElementById('cpu-bar').style.width = `${cpuUsage}%`;
|
||||
document.getElementById('memory-bar').style.width = `${memoryUsage}%`;
|
||||
document.getElementById('disk-bar').style.width = `${diskUsage}%`;
|
||||
|
||||
// Tools and plugins
|
||||
document.getElementById('tools-loaded').textContent = Math.floor(Math.random() * 20) + 5;
|
||||
document.getElementById('plugins-active').textContent = Math.floor(Math.random() * 5) + 1;
|
||||
|
||||
// Performance metrics
|
||||
const avgResponseTime = (Math.random() * 2).toFixed(3);
|
||||
document.getElementById('avg-response-time').textContent = `${avgResponseTime}s`;
|
||||
|
||||
const requestsPerMinute = Math.floor(Math.random() * 50) + 10;
|
||||
document.getElementById('requests-per-minute').textContent = requestsPerMinute;
|
||||
|
||||
const peakRequests = Math.floor(Math.random() * 100) + 50;
|
||||
document.getElementById('peak-requests').textContent = peakRequests;
|
||||
|
||||
// System info
|
||||
document.getElementById('system-hostname').textContent = 'maxclaw-agent';
|
||||
document.getElementById('system-platform').textContent = navigator.platform;
|
||||
document.getElementById('system-architecture').textContent = navigator.platform.includes('64') ? 'x64' : 'x86';
|
||||
document.getElementById('python-version').textContent = '3.11.0';
|
||||
|
||||
// Update logs
|
||||
updateLogs();
|
||||
}
|
||||
|
||||
// Update logs
|
||||
function updateLogs() {
|
||||
const logsContainer = document.getElementById('logs-container');
|
||||
|
||||
// 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'
|
||||
];
|
||||
|
||||
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 timestamp = new Date().toLocaleTimeString();
|
||||
|
||||
logsHtml += `<div class="log-entry log-${type}">[${timestamp}] ${message}</div>`;
|
||||
}
|
||||
|
||||
logsContainer.innerHTML = logsHtml;
|
||||
}
|
||||
|
||||
// Update last updated timestamp
|
||||
function updateLastUpdated() {
|
||||
const now = new Date();
|
||||
document.getElementById('last-updated').textContent = now.toLocaleString();
|
||||
}
|
||||
|
||||
// Show alert
|
||||
function showAlert(message, type) {
|
||||
const container = document.getElementById('alert-container');
|
||||
const alert = document.createElement('div');
|
||||
alert.className = `alert alert-${type}`;
|
||||
alert.textContent = message;
|
||||
|
||||
// Remove existing alerts
|
||||
container.innerHTML = '';
|
||||
container.appendChild(alert);
|
||||
|
||||
// Auto-remove after 5 seconds
|
||||
setTimeout(() => {
|
||||
if (alert.parentNode) {
|
||||
alert.parentNode.removeChild(alert);
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user