import { client } from "./mcp-client-local.js";
const OLLAMA_URL = "http://localhost:11434/api/chat";
const MODEL = "llama3.1";
// 1️⃣ Prompt para que sepa que es una persona, no un catálogo de funciones
const GIM_SYSTEM_PROMPT = `Eres el Soporte Técnico Humano del sistema GIM.
Tu objetivo es ayudar al usuario de forma conversacional.
Si necesitas información técnica, usa tus herramientas en segundo plano, pero al usuario respóndele siempre con frases completas en español.
NUNCA respondas con código JSON como {"name": ...}. Si vas a usar una herramienta, hazlo, y luego explica el resultado.`;
let chatHistory: any[] = [{ role: "system", content: GIM_SYSTEM_PROMPT }];
export async function processChatMessage(userInput: string) {
try {
chatHistory.push({ role: "user", content: userInput });
const listResponse = await client.listTools();
const tools = listResponse.tools.map(tool => ({
type: "function",
function: {
name: tool.name,
description: tool.description,
parameters: tool.inputSchema
}
}));
const response = await fetch(OLLAMA_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
model: MODEL,
messages: chatHistory,
tools,
stream: false
})
});
const data = await response.json();
let message = data.message;
// 2️⃣ Si el modelo devuelve una tool call, la ejecutamos internamente
if (message.tool_calls && message.tool_calls.length > 0) {
chatHistory.push(message);
for (const toolCall of message.tool_calls) {
const toolResult = await client.callTool({
name: toolCall.function.name,
arguments: toolCall.function.arguments ?? {}
});
const text = Array.isArray(toolResult.content)
? toolResult.content[0]?.text ?? ""
: JSON.stringify(toolResult.content);
chatHistory.push({
role: "tool",
tool_name: toolCall.function.name,
content: text
});
}
// Volvemos a llamar a Ollama para que traduzca el resultado a lenguaje humano
const secondRes = await fetch(OLLAMA_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ model: MODEL, messages: chatHistory, stream: false })
});
const secondData = await secondRes.json();
message = secondData.message;
}
// 3️⃣ Validación final: Si por algún motivo el contenido es JSON o está vacío
let finalContent = message.content;
if (!finalContent || finalContent.includes('{"name":')) {
finalContent = "Soy el asistente de soporte de GIM. Puedo ayudarte a conocer nuestras interacciones como las Flashcards. ¿Qué te gustaría saber?";
}
chatHistory.push({ role: "assistant", content: finalContent });
return finalContent;
} catch (error) {
console.error("Error:", error);
return "Lo siento, ha habido un problema técnico. ¿Podemos intentarlo de nuevo?";
}
}
export function resetChat() {
chatHistory = [{ role: "system", content: GIM_SYSTEM_PROMPT }];
}