diff --git a/src/commands/messages/AI/chat.ts b/src/commands/messages/AI/chat.ts index 84bd5e4..cf2d49d 100644 --- a/src/commands/messages/AI/chat.ts +++ b/src/commands/messages/AI/chat.ts @@ -1,6 +1,6 @@ import logger from "../../../core/lib/logger"; import { CommandMessage } from "../../../core/types/commands"; -import { TextChannel, DMChannel, ThreadChannel, EmbedBuilder, ChannelType } from "discord.js"; +import { TextChannel, DMChannel, ThreadChannel, ChannelType } from "discord.js"; import { aiService } from "../../../core/services/AIService"; /** @@ -124,17 +124,9 @@ export const command: CommandMessage = { run: async (message, args) => { // Validaciones básicas if (!args || args.length === 0) { - const helpEmbed = new EmbedBuilder() - .setColor(0xFF69B4) - .setTitle('❌ Error: Mensaje requerido') - .setDescription( - '**Uso:** `ai `\n' + - '**Ejemplo:** `ai ¿Cómo funciona JavaScript?`\n' + - '**Límite:** 4000 caracteres máximo' - ) - .setFooter({ text: 'AI Chat mejorado con Gemini 2.5 Flash' }); - - await message.reply({ embeds: [helpEmbed] }); + await message.reply({ + content: '**Uso:** `ai `\n**Ejemplo:** `ai ¿Cómo funciona JavaScript?`\n**Límite:** 4000 caracteres máximo' + }); return; } @@ -145,9 +137,7 @@ export const command: CommandMessage = { // Verificar tipo de canal const channel = message.channel as TextChannel | DMChannel | ThreadChannel; if (!channel || !('send' in channel)) { - await message.reply({ - content: "❌ **Error:** Este comando no se puede usar en este tipo de canal." - }); + await message.reply({ content: "❌ **Error:** Este comando no se puede usar en este tipo de canal." }); return; } @@ -171,49 +161,26 @@ export const command: CommandMessage = { { meta } ); - // Crear embed de respuesta mejorado - const embed = new EmbedBuilder() - .setColor(0xFF69B4) - .setTitle('🌸 Gemini-chan') - .setDescription(aiResponse) - .setFooter({ - text: `Solicitado por ${message.author.username}`, - icon_url: message.author.displayAvatarURL({ forceStatic: false }) - }) - .setTimestamp(); - - // Manejar respuestas largas de forma inteligente - if (aiResponse.length > 4000) { - // Dividir en chunks preservando markdown - const chunks = smartChunkText(aiResponse, 4000); - - for (let i = 0; i < chunks.length && i < 3; i++) { - const chunkEmbed = new EmbedBuilder() - .setColor(0xFF69B4) - .setTitle(i === 0 ? '🌸 Gemini-chan' : `🌸 Gemini-chan (${i + 1}/${chunks.length})`) - .setDescription(chunks[i]) - .setFooter({ - text: `Solicitado por ${message.author.username} | Parte ${i + 1}`, - icon_url: message.author.displayAvatarURL({ forceStatic: false }) - }) - .setTimestamp(); + // Discord limita el contenido a ~2000 caracteres + const MAX_CONTENT = 2000; + if (aiResponse.length > MAX_CONTENT) { + const chunks = smartChunkText(aiResponse, MAX_CONTENT); + for (let i = 0; i < chunks.length && i < 6; i++) { if (i === 0) { - await message.reply({ embeds: [chunkEmbed] }); + await message.reply({ content: chunks[i] }); } else { - await channel.send({ embeds: [chunkEmbed] }); + await channel.send({ content: chunks[i] }); // Pausa entre mensajes para evitar rate limits - await new Promise(resolve => setTimeout(resolve, 1000)); + await new Promise(resolve => setTimeout(resolve, 500)); } } - if (chunks.length > 3) { - await channel.send({ - content: "⚠️ **Nota:** La respuesta fue truncada. Intenta preguntas más específicas." - }); + if (chunks.length > 6) { + await channel.send({ content: "⚠️ Nota: La respuesta fue truncada. Intenta una pregunta más específica." }); } } else { - await message.reply({ embeds: [embed] }); + await message.reply({ content: aiResponse }); } // Log para monitoreo (solo en desarrollo) @@ -221,25 +188,9 @@ export const command: CommandMessage = { const stats = aiService.getStats(); logger.info(`AI Request completado - Usuario: ${userId}, Queue: ${stats.queueLength}, Conversaciones activas: ${stats.activeConversations}`); } - } catch (error: any) { logger.error(`Error en comando AI para usuario ${userId}:`, error); - - // Crear embed de error informativo - const errorEmbed = new EmbedBuilder() - .setColor(0xFF4444) - .setTitle('❌ Error del Servicio de IA') - .setDescription(error.message || 'Error desconocido del servicio') - .addFields({ - name: '💡 Consejos', - value: '• Verifica que tu mensaje no sea demasiado largo\n' + - '• Espera unos segundos entre consultas\n' + - '• Evita contenido inapropiado' - }) - .setFooter({ text: 'Si el problema persiste, contacta a un administrador' }) - .setTimestamp(); - - await message.reply({ embeds: [errorEmbed] }); + await message.reply({ content: `❌ Error del Servicio de IA: ${error.message || 'Error desconocido del servicio'}` }); } finally { // Limpiar indicador de escritura clearInterval(typingInterval); diff --git a/src/commands/messages/settings-server/settings.ts b/src/commands/messages/settings-server/settings.ts index 4e262dd..79aaefb 100644 --- a/src/commands/messages/settings-server/settings.ts +++ b/src/commands/messages/settings-server/settings.ts @@ -1,6 +1,6 @@ import logger from "../../../core/lib/logger"; import { CommandMessage } from "../../../core/types/commands"; -import { ComponentType } from "discord-api-types/v10"; +import { ComponentType, TextInputStyle } from "discord-api-types/v10"; import { hasManageGuildOrStaff } from "../../../core/lib/permissions"; import { aiService } from "../../../core/services/AIService"; @@ -212,13 +212,30 @@ export const command: CommandMessage = { const currentAiPrompt = currentServer?.aiRolePrompt ?? ''; const aiModal = { title: "🧠 Configurar AI Role Prompt", - custom_id: "ai_role_prompt_modal", + customId: "ai_role_prompt_modal", components: [ - { type: 1, components: [ { type: 4, custom_id: "ai_role_prompt_input", label: "Prompt de rol (opcional)", style: 2, placeholder: "Ej: Eres un asistente amistoso del servidor, responde en español, evita spoilers...", required: false, max_length: 1500, value: currentAiPrompt.slice(0, 1500) } ] } + { + type: ComponentType.Label, + label: "Prompt de rol (opcional)", + component: { + type: ComponentType.TextInput, + customId: "ai_role_prompt_input", + style: TextInputStyle.Paragraph, + required: false, + placeholder: "Ej: Eres un asistente amistoso del servidor, responde en español, evita spoilers...", + maxLength: 1500, + value: currentAiPrompt.slice(0, 1500) + } + } ] - }; + } as const; - await interaction.showModal(aiModal); + try { + await interaction.showModal(aiModal); + } catch (err) { + try { await interaction.reply({ content: '❌ No se pudo abrir el modal de AI.', flags: 64 }); } catch {} + return; + } try { const modalInteraction = await interaction.awaitModalSubmit({ @@ -226,7 +243,7 @@ export const command: CommandMessage = { filter: (m: any) => m.customId === 'ai_role_prompt_modal' && m.user.id === message.author.id }); - const newPromptRaw = modalInteraction.fields.getTextInputValue('ai_role_prompt_input') ?? ''; + const newPromptRaw = modalInteraction.components.getTextInputValue('ai_role_prompt_input') ?? ''; const newPrompt = newPromptRaw.trim(); const toSave: string | null = newPrompt.length > 0 ? newPrompt : null;