262 lines
6.7 KiB
JavaScript
262 lines
6.7 KiB
JavaScript
// main.js
|
|
const readline = require('readline');
|
|
const { callLLM } = require('./ai_client');
|
|
const { log } = require('./logger');
|
|
require('dotenv').config();
|
|
|
|
const rl = readline.createInterface({
|
|
input: process.stdin,
|
|
output: process.stdout
|
|
});
|
|
|
|
function question(prompt) {
|
|
return new Promise(resolve => {
|
|
rl.question(prompt, resolve);
|
|
});
|
|
}
|
|
|
|
function mostrarMenu() {
|
|
console.log("\n" + "=".repeat(60));
|
|
console.log("🤖 ASISTENTE IA - GESTIÓN TÉCNICA IT");
|
|
console.log("=".repeat(60));
|
|
console.log("1. Checklist técnico (salida estructurada)");
|
|
console.log("2. Transformación a plantilla ITIL");
|
|
console.log("3. Respuesta guiada (preguntas + respuesta final)");
|
|
console.log("4. Salir");
|
|
console.log("=".repeat(60));
|
|
}
|
|
|
|
async function checklistTecnico() {
|
|
console.log("\n📋 CHECKLIST TÉCNICO");
|
|
console.log("-".repeat(60));
|
|
|
|
const tema = await question("Introduce el tema técnico (ej: hardening SSH Debian): ");
|
|
|
|
const prompt = `Genera un checklist técnico detallado sobre "${tema}" en formato Markdown.
|
|
|
|
Estructura requerida:
|
|
# Checklist: ${tema}
|
|
|
|
## Items
|
|
Para cada item incluye:
|
|
- [ ] **Nombre del item**: Breve descripción
|
|
- **Justificación**: Por qué es importante
|
|
- **Riesgo si no se aplica**: Consecuencias de omitirlo
|
|
|
|
Genera entre 5 y 8 items relevantes. Sé específico y práctico.`;
|
|
|
|
console.log("\n⏳ Generando checklist...\n");
|
|
|
|
const startTime = Date.now();
|
|
try {
|
|
const respuesta = await callLLM(prompt, 1500);
|
|
const duration = Date.now() - startTime;
|
|
|
|
console.log(respuesta);
|
|
|
|
// Logging
|
|
log({
|
|
opcion: "checklist_tecnico",
|
|
proveedor: "ollama",
|
|
modelo: process.env.MODEL || "openchat",
|
|
tema: tema,
|
|
prompt_length: prompt.length,
|
|
parametros: { max_tokens: 1500 },
|
|
respuesta_length: respuesta.length,
|
|
duracion_ms: duration
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error("\n❌ Error:", error.message);
|
|
log({
|
|
opcion: "checklist_tecnico",
|
|
error: error.message,
|
|
tema: tema
|
|
});
|
|
}
|
|
}
|
|
|
|
async function transformacionITIL() {
|
|
console.log("\n📄 TRANSFORMACIÓN A PLANTILLA ITIL");
|
|
console.log("-".repeat(60));
|
|
|
|
console.log("Introduce el texto de la incidencia (escribe 'FIN' en una línea aparte para terminar):");
|
|
|
|
let textoIncidencia = "";
|
|
let linea;
|
|
while ((linea = await question("")) !== "FIN") {
|
|
textoIncidencia += linea + "\n";
|
|
}
|
|
|
|
const prompt = `Transforma el siguiente texto de incidencia en una plantilla ITIL estructurada:
|
|
|
|
TEXTO ORIGINAL:
|
|
${textoIncidencia}
|
|
|
|
PLANTILLA ITIL REQUERIDA:
|
|
|
|
## Resumen
|
|
[Descripción breve y clara del problema]
|
|
|
|
## Impacto
|
|
[Alto/Medio/Bajo - Afectación al negocio]
|
|
|
|
## Urgencia
|
|
[Alta/Media/Baja - Tiempo crítico de resolución]
|
|
|
|
## Acciones Realizadas
|
|
- [Lista de acciones ya tomadas]
|
|
|
|
## Evidencias
|
|
- [Logs, capturas, datos técnicos relevantes]
|
|
|
|
## Diagnóstico Preliminar
|
|
[Análisis de la causa probable]
|
|
|
|
## Próximos Pasos
|
|
1. [Primer paso]
|
|
2. [Segundo paso]
|
|
3. [Tercer paso]
|
|
|
|
Completa la plantilla de forma profesional y técnica.`;
|
|
|
|
console.log("\n⏳ Transformando a formato ITIL...\n");
|
|
|
|
const startTime = Date.now();
|
|
try {
|
|
const respuesta = await callLLM(prompt, 1200);
|
|
const duration = Date.now() - startTime;
|
|
|
|
console.log(respuesta);
|
|
|
|
// Logging
|
|
log({
|
|
opcion: "transformacion_itil",
|
|
proveedor: "ollama",
|
|
modelo: process.env.MODEL || "openchat",
|
|
texto_original_length: textoIncidencia.length,
|
|
parametros: { max_tokens: 1200 },
|
|
respuesta_length: respuesta.length,
|
|
duracion_ms: duration
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error("\n❌ Error:", error.message);
|
|
log({
|
|
opcion: "transformacion_itil",
|
|
error: error.message
|
|
});
|
|
}
|
|
}
|
|
|
|
async function respuestaGuiada() {
|
|
console.log("\n❓ RESPUESTA GUIADA");
|
|
console.log("-".repeat(60));
|
|
|
|
const solicitud = await question("Describe el problema (ej: no funciona la VPN): ");
|
|
|
|
const prompt = `Un usuario reporta: "${solicitud}"
|
|
|
|
Como técnico IT experto, necesitas:
|
|
|
|
1. **PREGUNTAS DE ACLARACIÓN** (3-5 preguntas específicas):
|
|
- Pregunta 1: [pregunta técnica específica]
|
|
- Pregunta 2: [pregunta sobre contexto]
|
|
- Pregunta 3: [pregunta sobre síntomas]
|
|
- [2 preguntas más si es necesario]
|
|
|
|
2. **HIPÓTESIS INICIAL**:
|
|
Basándote en la información limitada, cuál es la causa más probable.
|
|
|
|
3. **PLAN DE DIAGNÓSTICO** (pasos numerados):
|
|
1. [Primer paso de verificación]
|
|
2. [Segundo paso]
|
|
3. [Tercer paso]
|
|
4. [Cuarto paso]
|
|
5. [Quinto paso si es necesario]
|
|
|
|
Proporciona una respuesta estructurada y profesional.`;
|
|
|
|
console.log("\n⏳ Analizando y generando preguntas...\n");
|
|
|
|
const startTime = Date.now();
|
|
try {
|
|
const respuesta = await callLLM(prompt, 1000);
|
|
const duration = Date.now() - startTime;
|
|
|
|
console.log(respuesta);
|
|
|
|
// Logging
|
|
log({
|
|
opcion: "respuesta_guiada",
|
|
proveedor: "ollama",
|
|
modelo: process.env.MODEL || "openchat",
|
|
solicitud: solicitud,
|
|
parametros: { max_tokens: 1000 },
|
|
respuesta_length: respuesta.length,
|
|
duracion_ms: duration
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error("\n❌ Error:", error.message);
|
|
log({
|
|
opcion: "respuesta_guiada",
|
|
error: error.message,
|
|
solicitud: solicitud
|
|
});
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
// Verificar variables de entorno
|
|
if (!process.env.OLLAMA_URL) {
|
|
console.log("⚠️ Usando URL por defecto de Ollama: http://localhost:11434/api/generate");
|
|
}
|
|
|
|
let continuar = true;
|
|
|
|
while (continuar) {
|
|
mostrarMenu();
|
|
const opcion = await question("\nSelecciona una opción (1-4): ");
|
|
|
|
switch (opcion.trim()) {
|
|
case "1":
|
|
await checklistTecnico();
|
|
break;
|
|
case "2":
|
|
await transformacionITIL();
|
|
break;
|
|
case "3":
|
|
await respuestaGuiada();
|
|
break;
|
|
case "4":
|
|
console.log("\n👋 ¡Hasta pronto!");
|
|
continuar = false;
|
|
break;
|
|
default:
|
|
console.log("\n❌ Opción no válida. Por favor, selecciona 1-4.");
|
|
}
|
|
|
|
if (continuar) {
|
|
await question("\nPresiona ENTER para continuar...");
|
|
}
|
|
}
|
|
|
|
rl.close();
|
|
}
|
|
|
|
// Manejo de errores global
|
|
process.on('unhandledRejection', (error) => {
|
|
console.error('\n❌ Error no manejado:', error.message);
|
|
log({
|
|
tipo: "error_no_manejado",
|
|
error: error.message,
|
|
stack: error.stack
|
|
});
|
|
});
|
|
|
|
// Ejecutar
|
|
main().catch(error => {
|
|
console.error("❌ Error fatal:", error.message);
|
|
process.exit(1);
|
|
}); |