feat: add admin controls for AI system management including cache clearing, full reset, and configuration panel
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import { CommandMessage } from "../../../core/types/commands";
|
||||
import { EmbedBuilder, PermissionFlagsBits } from "discord.js";
|
||||
import { PermissionFlagsBits } from "discord.js";
|
||||
import { aiService } from "../../../core/services/AIService";
|
||||
import logger from "../../../core/lib/logger";
|
||||
|
||||
const OWNER_ID = '327207082203938818';
|
||||
/**
|
||||
* Formatear tiempo de actividad
|
||||
*/
|
||||
@@ -19,30 +19,138 @@ function formatUptime(seconds: number): string {
|
||||
/**
|
||||
* Formatear bytes a formato legible
|
||||
*/
|
||||
function formatBytes(bytes: number): string {
|
||||
if (bytes === 0) return '0 Bytes';
|
||||
function formatBytesMB(bytes: number): string {
|
||||
return (bytes / 1024 / 1024).toFixed(1) + 'MB';
|
||||
}
|
||||
|
||||
const k = 1024;
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
/**
|
||||
* Construir panel de administración de IA
|
||||
*/
|
||||
function buildAIAdminPanel() {
|
||||
const stats = aiService.getStats();
|
||||
const uptime = process.uptime();
|
||||
const memoryUsage = process.memoryUsage();
|
||||
const now = new Date();
|
||||
const ts = now.toISOString().replace('T', ' ').split('.')[0];
|
||||
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
||||
// Estados del sistema
|
||||
const queueStatus = stats.queueLength === 0 ? '🟢 Normal' :
|
||||
stats.queueLength < 5 ? '🟡 Ocupado' : '🔴 Saturado';
|
||||
const memoryStatus = memoryUsage.heapUsed / memoryUsage.heapTotal > 0.8 ? '🔴 Alta' : '🟢 Normal';
|
||||
|
||||
const rss = formatBytesMB(memoryUsage.rss);
|
||||
const heapUsed = formatBytesMB(memoryUsage.heapUsed);
|
||||
const heapTotal = formatBytesMB(memoryUsage.heapTotal);
|
||||
const external = formatBytesMB(memoryUsage.external);
|
||||
|
||||
// @ts-ignore
|
||||
return {
|
||||
type: 17,
|
||||
accent_color: 0xFF69B4,
|
||||
components: [
|
||||
{
|
||||
type: 10,
|
||||
content: '## 🌸 Panel de Administración - Gemini-chan'
|
||||
},
|
||||
{
|
||||
type: 10,
|
||||
content: '-# Gestiona el sistema de IA y monitorea estadísticas en tiempo real.'
|
||||
},
|
||||
{ type: 14, divider: true, spacing: 1 },
|
||||
{
|
||||
type: 9,
|
||||
components: [
|
||||
{ type: 10, content: `🔄 **Conversaciones Activas:** ${stats.activeConversations}` }
|
||||
],
|
||||
accessory: {
|
||||
type: 2,
|
||||
style: 1,
|
||||
emoji: "🧹",
|
||||
label: 'Limpiar Cache',
|
||||
custom_id: 'ai_clear_cache'
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 9,
|
||||
components: [
|
||||
{ type: 10, content: `📊 **Requests en Cola:** ${stats.queueLength} | **Estado:** ${queueStatus}` }
|
||||
],
|
||||
accessory: {
|
||||
type: 2,
|
||||
style: 1,
|
||||
emoji: "🔄",
|
||||
label: 'Refrescar Stats',
|
||||
custom_id: 'ai_refresh_stats'
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 9,
|
||||
components: [
|
||||
{ type: 10, content: `⏱️ **Total Requests:** ${stats.totalRequests} | **Uptime:** ${formatUptime(uptime)}` }
|
||||
],
|
||||
accessory: {
|
||||
type: 2,
|
||||
style: 2,
|
||||
emoji: "🔧",
|
||||
label: 'Configuración',
|
||||
custom_id: 'ai_config'
|
||||
}
|
||||
},
|
||||
{ type: 14, divider: true, spacing: 1 },
|
||||
{
|
||||
type: 10,
|
||||
content: ` ## 🧠 Uso de Memoria del Sistema IA
|
||||
\`\`\`
|
||||
┌─────────────────┬──────────────┬──────────┐
|
||||
│ Memory Type │ Usage │ Status │
|
||||
├─────────────────┼──────────────┼──────────┤
|
||||
│ RSS │ ${rss.padEnd(12)} │ Normal │
|
||||
│ Heap Used │ ${heapUsed.padEnd(12)} │ ${memoryStatus.padEnd(8)} │
|
||||
│ Heap Total │ ${heapTotal.padEnd(12)} │ Normal │
|
||||
│ External │ ${external.padEnd(12)} │ Normal │
|
||||
└─────────────────┴──────────────┴──────────┘
|
||||
|
||||
📈 Configuración Actual:
|
||||
• Rate Limit: 20 req/min por usuario
|
||||
• Cooldown: 3 segundos entre requests
|
||||
• Max Tokens: 1M entrada / 8K salida
|
||||
• Max Concurrent: 3 requests simultáneos
|
||||
• Modelo: gemini-1.5-flash
|
||||
\`\`\`
|
||||
Última actualización: ${ts} UTC
|
||||
|
||||
⚠️ **Nota:** El sistema se resetea automáticamente cada 30 minutos para optimizar memoria.`
|
||||
},
|
||||
{ type: 14, divider: true, spacing: 1 },
|
||||
{
|
||||
type: 9,
|
||||
components: [
|
||||
{ type: 10, content: "<:Sup_urg:1420535068056748042> **REINICIAR** todo el sistema de IA (limpia cache, conversaciones y estadísticas)" }
|
||||
],
|
||||
accessory: {
|
||||
type: 2,
|
||||
style: 4,
|
||||
emoji: "⚠️",
|
||||
label: 'RESET COMPLETO',
|
||||
custom_id: 'ai_full_reset'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
export const command: CommandMessage = {
|
||||
name: 'aistats',
|
||||
type: "message",
|
||||
aliases: ['ai-stats', 'ai-info'],
|
||||
aliases: ['ai-stats', 'ai-info', 'ai-panel'],
|
||||
cooldown: 5,
|
||||
description: 'Muestra estadísticas del servicio de IA (Solo administradores)',
|
||||
description: 'Panel de administración del sistema de IA (Solo administradores)',
|
||||
category: 'Administración',
|
||||
usage: 'aistats [reset]',
|
||||
run: async (message, args) => {
|
||||
// Verificar permisos de administrador
|
||||
if (!message.member?.permissions.has(PermissionFlagsBits.Administrator)) {
|
||||
await message.reply({
|
||||
content: "❌ **Error:** Necesitas permisos de administrador para usar este comando."
|
||||
});
|
||||
if (message.author.id !== OWNER_ID) {
|
||||
await message.reply({ content: '❌ No tienes permisos para usar este panel.' });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -51,82 +159,71 @@ export const command: CommandMessage = {
|
||||
|
||||
// Reset del sistema si se solicita
|
||||
if (action === 'reset') {
|
||||
// Aquí puedes agregar lógica para resetear estadísticas
|
||||
const resetEmbed = new EmbedBuilder()
|
||||
.setColor(0x00FF00)
|
||||
.setTitle('✅ Sistema de IA Reiniciado')
|
||||
.setDescription('Las estadísticas y cache han sido limpiados exitosamente.')
|
||||
.setTimestamp();
|
||||
// @ts-ignore
|
||||
const resetPanel = {
|
||||
type: 17,
|
||||
accent_color: 0x00FF00,
|
||||
components: [
|
||||
{
|
||||
type: 10,
|
||||
content: '## ✅ Sistema de IA Reiniciado'
|
||||
},
|
||||
{
|
||||
type: 10,
|
||||
content: 'Las estadísticas, cache y conversaciones han sido limpiados exitosamente.'
|
||||
},
|
||||
{ type: 14, divider: true, spacing: 1 },
|
||||
{
|
||||
type: 10,
|
||||
content: `🔄 **Estado:** Sistema reiniciado\n⏰ **Timestamp:** ${new Date().toISOString().replace('T', ' ').split('.')[0]} UTC\n👤 **Administrador:** ${message.author.username}`
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
await message.reply({ embeds: [resetEmbed] });
|
||||
await message.reply({
|
||||
content: '',
|
||||
components: [resetPanel]
|
||||
});
|
||||
logger.info(`Sistema de IA reiniciado por ${message.author.username} (${message.author.id})`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Obtener estadísticas del servicio
|
||||
const stats = aiService.getStats();
|
||||
const uptime = process.uptime();
|
||||
const memoryUsage = process.memoryUsage();
|
||||
// Mostrar panel principal
|
||||
const adminPanel = buildAIAdminPanel();
|
||||
|
||||
// Crear embed de estadísticas detallado
|
||||
const statsEmbed = new EmbedBuilder()
|
||||
.setColor(0xFF69B4)
|
||||
.setTitle('📊 Estadísticas del Servicio de IA')
|
||||
.setDescription('Estado actual del sistema Gemini-chan')
|
||||
.addFields([
|
||||
{
|
||||
name: '🔄 Queue y Conversaciones',
|
||||
value: `**Conversaciones Activas:** ${stats.activeConversations}\n` +
|
||||
`**Requests en Cola:** ${stats.queueLength}\n` +
|
||||
`**Total Requests:** ${stats.totalRequests}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: '⚡ Rendimiento',
|
||||
value: `**Uptime:** ${formatUptime(uptime)}\n` +
|
||||
`**Memoria RAM:** ${formatBytes(memoryUsage.heapUsed)} / ${formatBytes(memoryUsage.heapTotal)}\n` +
|
||||
`**RSS:** ${formatBytes(memoryUsage.rss)}`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: '🛡️ Límites y Configuración',
|
||||
value: `**Rate Limit:** 20 req/min por usuario\n` +
|
||||
`**Cooldown:** 3 segundos\n` +
|
||||
`**Max Tokens:** 1M entrada / 8K salida\n` +
|
||||
`**Max Concurrent:** 3 requests`,
|
||||
inline: false
|
||||
}
|
||||
])
|
||||
.setFooter({
|
||||
text: `Solicitado por ${message.author.username} | Usa 'aistats reset' para reiniciar`,
|
||||
iconURL: message.author.displayAvatarURL({ forceStatic: false })
|
||||
})
|
||||
.setTimestamp();
|
||||
|
||||
// Agregar indicador de estado del sistema
|
||||
const queueStatus = stats.queueLength === 0 ? '🟢 Normal' :
|
||||
stats.queueLength < 5 ? '🟡 Ocupado' : '🔴 Saturado';
|
||||
|
||||
statsEmbed.addFields({
|
||||
name: '🎯 Estado del Sistema',
|
||||
value: `**Cola:** ${queueStatus}\n` +
|
||||
`**API:** 🟢 Operativa\n` +
|
||||
`**Memoria:** ${memoryUsage.heapUsed / memoryUsage.heapTotal > 0.8 ? '🔴 Alta' : '🟢 Normal'}`,
|
||||
inline: true
|
||||
await message.reply({
|
||||
content: '',
|
||||
components: [adminPanel]
|
||||
});
|
||||
|
||||
await message.reply({ embeds: [statsEmbed] });
|
||||
|
||||
} catch (error: any) {
|
||||
logger.error('Error obteniendo estadísticas de IA:', error);
|
||||
|
||||
const errorEmbed = new EmbedBuilder()
|
||||
.setColor(0xFF4444)
|
||||
.setTitle('❌ Error')
|
||||
.setDescription('No se pudieron obtener las estadísticas del sistema.')
|
||||
.setTimestamp();
|
||||
// @ts-ignore
|
||||
const errorPanel = {
|
||||
type: 17,
|
||||
accent_color: 0xFF4444,
|
||||
components: [
|
||||
{
|
||||
type: 10,
|
||||
content: '## ❌ Error del Sistema'
|
||||
},
|
||||
{
|
||||
type: 10,
|
||||
content: 'No se pudieron obtener las estadísticas del sistema de IA.'
|
||||
},
|
||||
{ type: 14, divider: true, spacing: 1 },
|
||||
{
|
||||
type: 10,
|
||||
content: `**Error:** ${error.message || 'Error desconocido'}\n**Timestamp:** ${new Date().toISOString()}`
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
await message.reply({ embeds: [errorEmbed] });
|
||||
await message.reply({
|
||||
content: '',
|
||||
components: [errorPanel]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user