feat: refactor admin panel interactions to use Discord.js 14.22.1 API with enhanced ownership checks and updated UI components

This commit is contained in:
2025-10-02 22:50:27 -05:00
parent 66c46ef6df
commit 0e8aae77b1
5 changed files with 243 additions and 479 deletions

View File

@@ -1,8 +1,10 @@
import { CommandMessage } from "../../../core/types/commands";
import { PermissionFlagsBits } from "discord.js";
import { ContainerBuilder, TextDisplayBuilder, SectionBuilder, ButtonBuilder, ButtonStyle, MessageFlags } from "discord.js";
import { aiService } from "../../../core/services/AIService";
import logger from "../../../core/lib/logger";
const OWNER_ID = '327207082203938818';
/**
* Formatear tiempo de actividad
*/
@@ -24,7 +26,7 @@ function formatBytesMB(bytes: number): string {
}
/**
* Construir panel de administración de IA
* Construir panel de administración de IA usando la API REAL de Discord.js 14.22.1
*/
function buildAIAdminPanel() {
const stats = aiService.getStats();
@@ -43,63 +45,53 @@ function buildAIAdminPanel() {
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
// Crear texto de header
const headerText = new TextDisplayBuilder()
.setContent('## 🌸 Panel de Administración - Gemini-chan\n-# Gestiona el sistema de IA y monitorea estadísticas en tiempo real.');
// Crear secciones con estadísticas
const statsSection1 = new SectionBuilder()
.addTextDisplayComponents(
new TextDisplayBuilder()
.setContent(`🔄 **Conversaciones Activas:** ${stats.activeConversations}`)
)
.setButtonAccessory(
new ButtonBuilder()
.setCustomId('ai_clear_cache')
.setLabel('Limpiar Cache')
.setEmoji('🧹')
.setStyle(ButtonStyle.Primary)
);
const statsSection2 = new SectionBuilder()
.addTextDisplayComponents(
new TextDisplayBuilder()
.setContent(`📊 **Requests en Cola:** ${stats.queueLength} | **Estado:** ${queueStatus}`)
)
.setButtonAccessory(
new ButtonBuilder()
.setCustomId('ai_refresh_stats')
.setLabel('Refrescar Stats')
.setEmoji('🔄')
.setStyle(ButtonStyle.Primary)
);
const configSection = new SectionBuilder()
.addTextDisplayComponents(
new TextDisplayBuilder()
.setContent(`⏱️ **Total Requests:** ${stats.totalRequests} | **Uptime:** ${formatUptime(uptime)}`)
)
.setButtonAccessory(
new ButtonBuilder()
.setCustomId('ai_config')
.setLabel('Configuración')
.setEmoji('🔧')
.setStyle(ButtonStyle.Secondary)
);
// Texto de memoria
const memoryText = new TextDisplayBuilder()
.setContent(`## 🧠 Uso de Memoria del Sistema IA
\`\`\`
┌─────────────────┬──────────────┬──────────┐
│ Memory Type │ Usage │ Status │
@@ -110,33 +102,32 @@ function buildAIAdminPanel() {
│ 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
📈 Configuración: 20 req/min | 3s cooldown | 1M/8K tokens | 3 concurrent
\`\`\`
Última actualización: ${ts} UTC
🔄 Ú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'
}
}
]
};
// Sección de reset
const resetSection = new SectionBuilder()
.addTextDisplayComponents(
new TextDisplayBuilder()
.setContent("**REINICIAR** todo el sistema de IA")
)
.setButtonAccessory(
new ButtonBuilder()
.setCustomId('ai_full_reset')
.setLabel('RESET COMPLETO')
.setEmoji('⚠️')
.setStyle(ButtonStyle.Danger)
);
// Construir container principal
const container = new ContainerBuilder()
.addTextDisplayComponents(headerText)
.addSectionComponents(statsSection1, statsSection2, configSection)
.addTextDisplayComponents(memoryText)
.addSectionComponents(resetSection);
return container;
}
export const command: CommandMessage = {
@@ -144,13 +135,13 @@ export const command: CommandMessage = {
type: "message",
aliases: ['ai-stats', 'ai-info', 'ai-panel'],
cooldown: 5,
description: 'Panel de administración del sistema de IA (Solo administradores)',
description: 'Panel de administración del sistema de IA (Solo el dueño)',
category: 'Administración',
usage: 'aistats [reset]',
run: async (message, args) => {
// Verificar permisos de administrador
// Verificar que sea el dueño del bot (MUY CRÍTICO)
if (message.author.id !== OWNER_ID) {
await message.reply({ content: '❌ No tienes permisos para usar este panel.' });
await message.reply({ content: '❌ Solo el dueño del bot puede usar este panel administrativo.' });
return;
}
@@ -159,32 +150,17 @@ export const command: CommandMessage = {
// Reset del sistema si se solicita
if (action === 'reset') {
// @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}`
}
]
};
const resetContainer = new ContainerBuilder()
.addTextDisplayComponents(
new TextDisplayBuilder()
.setContent('## ✅ Sistema de IA Reiniciado\nLas estadísticas, cache y conversaciones han sido limpiados exitosamente.\n\n🔄 **Estado:** Sistema reiniciado\n⏰ **Timestamp:** ' + new Date().toISOString().replace('T', ' ').split('.')[0] + ' UTC\n👤 **Dueño:** ' + message.author.username)
);
await message.reply({
flags: 32768,
components: [resetPanel]
components: [resetContainer],
flags: MessageFlags.IsComponentsV2
});
logger.info(`Sistema de IA reiniciado por ${message.author.username} (${message.author.id})`);
logger.info(`Sistema de IA reiniciado por el dueño ${message.author.username} (${message.author.id})`);
return;
}
@@ -192,38 +168,26 @@ export const command: CommandMessage = {
const adminPanel = buildAIAdminPanel();
await message.reply({
flags: 32768,
components: [adminPanel]
components: [adminPanel],
flags: MessageFlags.IsComponentsV2
});
} catch (error: any) {
logger.error('Error obteniendo estadísticas de IA:', error);
// @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()}`
}
]
};
const errorContainer = new ContainerBuilder()
.addTextDisplayComponents(
new TextDisplayBuilder()
.setContent('## ❌ Error del Sistema\nNo se pudieron obtener las estadísticas del sistema de IA.\n\n**Error:** ' + (error.message || 'Error desconocido') + '\n**Timestamp:** ' + new Date().toISOString())
);
await message.reply({
flags: 32768,
components: [errorPanel]
components: [errorContainer],
flags: MessageFlags.IsComponentsV2
});
}
}
}
// Exportar función para reutilizar en botones
export { buildAIAdminPanel };