este agent quedo funcionando al 100 en local al menos
This commit is contained in:
7
Makefile
7
Makefile
@@ -38,10 +38,15 @@ sync-to-gitea:
|
||||
|
||||
# Declaramos el target como PHONY ya que no corresponde a un archivo real (opcional pero recomendado)
|
||||
|
||||
.PHONY: UI agent
|
||||
.PHONY: UI agent mcp api
|
||||
UI:
|
||||
cd ui && ( if not exist node_modules npm install ) && npm run dev
|
||||
|
||||
agent:
|
||||
cd agent && npm install && npm run dev
|
||||
|
||||
mcp:
|
||||
cd mcp && npm install && npm run dev
|
||||
|
||||
api:
|
||||
cd api && npm install && npm run dev
|
||||
@@ -2,18 +2,18 @@ import { genAI, getMcpTool } from '../llm/gemini';
|
||||
import { FunctionCallingConfigMode } from '@google/genai';
|
||||
|
||||
export async function executeTools(instruction: string): Promise<string> {
|
||||
console.log('llamando herramienta');
|
||||
if (!genAI) throw new Error('LLM not configured');
|
||||
const mcpTool = await getMcpTool();
|
||||
const executionPrompt = `Vas a ejecutar una sola herramienta del MCP seg\xFAn el plan. Explic\xE1 brevemente la acci\xF3n y devuelve s\xF3lo el resultado.`;
|
||||
const fullPrompt = `${executionPrompt}\n${instruction}`
|
||||
console.log('---prompt---', fullPrompt);
|
||||
|
||||
const result = await genAI.models.generateContent({
|
||||
model: 'gemini-pro',
|
||||
contents: [{ role: 'user', parts: [{ text: `${executionPrompt}\n${instruction}` }] }],
|
||||
model: 'gemini-2.0-flash',
|
||||
contents: [{ role: 'user', parts: [{ text: fullPrompt }] }],
|
||||
config: {
|
||||
tools: [mcpTool],
|
||||
toolConfig: {
|
||||
functionCallingConfig: { mode: FunctionCallingConfigMode.ANY },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -4,30 +4,27 @@ import { systemPrompt } from '../systemPrompt';
|
||||
import type { Conversation } from '../types';
|
||||
|
||||
export async function generatePlan(conversation: Conversation, cognitionPrompt: string): Promise<string> {
|
||||
console.log('generando plan');
|
||||
|
||||
if (!genAI) throw new Error('LLM not configured');
|
||||
|
||||
const mcpTool = await getMcpTool();
|
||||
const planExecutionPrompt = `Est\xE1s generando el plan de acci\xF3n. Solo deb\xE9s consultar el MCP para listar sus capacidades disponibles y luego describir qu\xE9 pasos seguir. Si ya no hay tareas, inclu\xED la frase \"respuesta final\".`;
|
||||
const planExecutionPrompt = `Est\xE1s generando el plan de acci\xF3n.
|
||||
Solo deb\xE9s consultar el MCP para listar sus capacidades disponibles
|
||||
y luego describir qu\xE9 pasos seguir. Si ya no hay tareas, inclu\xED
|
||||
la frase \"respuesta final\".`;
|
||||
|
||||
const context = conversation.messages
|
||||
.map(m => {
|
||||
const sender = conversation.participants.find(p => p.id === m.from)?.name || m.from;
|
||||
const content = m.text || `[${m.type}]`;
|
||||
return `${sender}: ${content}`;
|
||||
})
|
||||
.join('\n');
|
||||
|
||||
const prompt = `${systemPrompt}\nConversation:\n${context}\n\nCognition:\n${cognitionPrompt}\n\n${planExecutionPrompt}\nPlan:`;
|
||||
const prompt = `${systemPrompt}\nConversation:\n${conversation}\n\nCognition:\n${JSON.stringify(conversation)}\n\n${planExecutionPrompt}\nPlan:`;
|
||||
const result = await genAI.models.generateContent({
|
||||
model: 'gemini-pro',
|
||||
contents: [{ role: 'user', parts: [{ text: prompt }] }],
|
||||
model: 'gemini-2.0-flash',
|
||||
contents: prompt,
|
||||
config: {
|
||||
tools: [mcpTool],
|
||||
toolConfig: {
|
||||
functionCallingConfig: { mode: FunctionCallingConfigMode.ANY },
|
||||
},
|
||||
},
|
||||
});
|
||||
console.log('------plan generado--------');
|
||||
|
||||
const text = (result as any).text || '';
|
||||
return text.trim();
|
||||
}
|
||||
|
||||
@@ -11,21 +11,21 @@ export async function iniciarProcesoCognitivo({ conversation }: CognitionArgs) {
|
||||
console.log('Iniciando proceso cognitivo...');
|
||||
let cognitionPrompt = '';
|
||||
let loopCount = 0;
|
||||
const plan = await generatePlan(conversation, cognitionPrompt);
|
||||
|
||||
while (loopCount < 5) {
|
||||
const plan = await generatePlan(conversation, cognitionPrompt);
|
||||
cognitionPrompt += `\n## Plan\n${plan}\n`;
|
||||
|
||||
if (/respuesta final/i.test(plan)) {
|
||||
break;
|
||||
}
|
||||
|
||||
const toolResult = await executeTools(plan);
|
||||
console.log('resultado de la herramienta ', toolResult);
|
||||
cognitionPrompt += `\n## Resultado\n${toolResult}\n`;
|
||||
loopCount += 1;
|
||||
}
|
||||
|
||||
console.log('Proceso cognitivo completado.');
|
||||
console.log('Proceso cognitivo completado.✅✅✅✅✅');
|
||||
return { text: cognitionPrompt };
|
||||
} catch (error) {
|
||||
console.error('Error al iniciar el proceso cognitivo:', error);
|
||||
|
||||
29
agent/src/cognition/normalResponse.ts
Normal file
29
agent/src/cognition/normalResponse.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { genAI, getMcpTool } from '../llm/gemini';
|
||||
import { FunctionCallingConfigMode, GenerateContentResponse } from '@google/genai';
|
||||
import { systemPrompt } from '../systemPrompt';
|
||||
import type { Conversation } from '../types';
|
||||
|
||||
export async function normalResponse(conversation: Conversation): Promise<GenerateContentResponse> {
|
||||
console.log('generando plan');
|
||||
|
||||
if (!genAI) throw new Error('LLM not configured');
|
||||
|
||||
const mcpTool = await getMcpTool();
|
||||
const planExecutionPrompt = `
|
||||
si necesitas ejecutar mas de una herremienta despues de otra para obtener la respuesta hacelo
|
||||
`;
|
||||
|
||||
|
||||
const prompt = `${systemPrompt}\nConversation:\n${JSON.stringify(conversation)}\n\nCognition:\n${planExecutionPrompt}`;
|
||||
const result = await genAI.models.generateContent({
|
||||
model: 'gemini-2.0-flash',
|
||||
contents: prompt,
|
||||
config: {
|
||||
tools: [mcpTool],
|
||||
},
|
||||
});
|
||||
console.log('------respuesta normal generada--------');
|
||||
|
||||
const text = (result as any).text || '';
|
||||
return result
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import { genAI, getMcpTool } from './llm/gemini';
|
||||
|
||||
import { systemPrompt } from './systemPrompt'; // Import the repository info from a separate file
|
||||
import { iniciarProcesoCognitivo } from './cognition/index'; // Import the MCP function to start cognitive processes
|
||||
import {normalResponse} from './cognition/normalResponse'
|
||||
import type { Conversation, Msg, Participant } from './types'; // Import the Conversation type
|
||||
import dotenv from 'dotenv';
|
||||
|
||||
@@ -12,8 +13,6 @@ dotenv.config();
|
||||
|
||||
|
||||
const PORT = Number(process.env.PORT) || 8001;
|
||||
const API_KEY = process.env.GEMINI_API_KEY || '';
|
||||
console.log(`Using Gemini API key: ${API_KEY}`);
|
||||
|
||||
|
||||
|
||||
@@ -44,14 +43,14 @@ app.post('/', async (req, res) => {
|
||||
return `${sender}: ${content}`;
|
||||
})
|
||||
.join('\n');
|
||||
|
||||
console.log('primero')
|
||||
if (!genAI) {
|
||||
return res.json({ reply: systemPrompt });
|
||||
return res.json({ reply: "por el momento parece que no tengo acceso a ningun llm ⚠️" });
|
||||
}
|
||||
|
||||
try {
|
||||
const contents = `${systemPrompt}\nConversation:\n${context}\n`;
|
||||
const result = await iniciarProcesoCognitivo({ conversation })
|
||||
const contents = `${systemPrompt}\nConversation:\n${conversation}\n`;
|
||||
const result = await normalResponse(conversation)
|
||||
const reply = (result.text || '').trim();
|
||||
res.json({ reply });
|
||||
} catch (err: any) {
|
||||
|
||||
@@ -1,20 +1,48 @@
|
||||
import { GoogleGenAI, mcpToTool } from '@google/genai';
|
||||
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
||||
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
||||
import dotenv from 'dotenv';
|
||||
dotenv.config();
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.log('modo desarrollo');
|
||||
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||
}else{
|
||||
console.log('modo produccion');
|
||||
}
|
||||
|
||||
if (
|
||||
process.env.NODE_ENV !== 'development' &&
|
||||
process.env.NODE_TLS_REJECT_UNAUTHORIZED === '0'
|
||||
) {
|
||||
throw new Error('NODE_TLS_REJECT_UNAUTHORIZED está activado en producción. Abortando.');
|
||||
}
|
||||
|
||||
|
||||
|
||||
const API_KEY = process.env.GEMINI_API_KEY || '';
|
||||
const MCP_URL = process.env.MCP_URL || 'http://planilla.interno.com/mcp';
|
||||
|
||||
console.log('segundo')
|
||||
export const genAI = API_KEY ? new GoogleGenAI({ apiKey: API_KEY }) : null;
|
||||
console.log(`Using Gemini API key: ${API_KEY}- ${!!genAI}`);
|
||||
|
||||
let mcpClient: Client | undefined;
|
||||
let mcpTransport: StreamableHTTPClientTransport | undefined;
|
||||
|
||||
export async function getMcpTool() {
|
||||
console.log('mcpURL ', MCP_URL);
|
||||
|
||||
if (!mcpClient) {
|
||||
mcpClient = new Client({ name: 'planilla-client', version: '1.0.0' });
|
||||
mcpTransport = new StreamableHTTPClientTransport(new URL(MCP_URL));
|
||||
await mcpClient.connect(mcpTransport);
|
||||
}
|
||||
return mcpToTool(mcpClient);
|
||||
// console.log('mcpClient ', mcpClient);
|
||||
const tool = mcpToTool(mcpClient);
|
||||
console.log('---------------------terminado getMcpTool---------------------------------------------------');
|
||||
|
||||
// console.log('tool ', tool);
|
||||
return tool;
|
||||
}
|
||||
|
||||
92
agent/src/systemPrompt copy.ts
Normal file
92
agent/src/systemPrompt copy.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
export const systemPrompt = `
|
||||
# 🟢 System Prompt — Agente de Planillas
|
||||
|
||||
|
||||
## Como funcionas
|
||||
- la fecha de hoy es ${new Date().toLocaleString('es-HN', { timeZone: 'America/Tegucigalpa', hour12: false, year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' })}
|
||||
- tu nombre es nucleo "id": "50493849962@c.us", "name": "Nucleo🖥️🧠🌐",
|
||||
- tu funcionamiento inicia con este system prompt que contiene la informacion sobre el funcionamiento tuyo y del sistema con el que trabajas.
|
||||
- vos estas conectado a dos interfaces: una de UI chat y otra por whatsapp. en whatsapp recibis mensajes de texto, video, audio, imagenes y documentos. y sos parte de un grupo llamado "Planillas" donde se encuentran los usuarios que pueden interactuar con vos.
|
||||
- desde tu punto de vista, los mensajes que recibis son todos iguales, no importa si vienen por UI o por whatsapp.
|
||||
- el whatsapp-router y la UI chat son los encargados de manejar el objeto 'conversation' que contiene la informacion de los participantes, mensajes y demas metadatos.
|
||||
- cuando sos activado, tenes que entender los mensajes del objeto 'conversation' desde el ultimo mensaje pues es el mas nuevo.
|
||||
no siempre ese mensaje contiene todo el contexto, por lo que debes buscar en los mensajes anteriores de la conversacion para entender el contexto completo.
|
||||
- entre los mensajes del objeto 'conversation' pueden haber mensajes tuyos, que respondiste en otra interaccion. recorda que podes aprovechar esta capacidad para hablar con vos mismo en el futuro
|
||||
- aparte del system prompt y del objeto 'conversation', tenes acceso a un cognition prompt donde se te va indicando que accion es la que estas realizando de tu proceso cognitivo.
|
||||
- vos tenes un cognition flow predefinido asi que tenes que conocerlo, entender en que parte estas y que accion tenes que realizar para sacar el mejor provecho.
|
||||
- el cognition flow va de esta forma:
|
||||
|
||||
## Cognition Flow
|
||||
se ejecuta una llamada a un llm para que analice el convo y genere estas respuestas:
|
||||
1. **Identificar al hablante**: ¿Quién está escribiendo? ¿Es un usuario conocido?
|
||||
${'variable respuestaIdentidadHablante'}
|
||||
2. **Entender el mensaje**: ¿Qué pregunta o solicitud se está haciendo?
|
||||
${'variable respuestaEntenderMensaje'}
|
||||
3. **Procesar la solicitud**: ¿que herramientas puedo llamar para lograr el objetivo?
|
||||
${'variable respuestaProcesarSolicitud'}
|
||||
4. **Responder al usuario**: una vez hayas llenado las primeras dos variables y provisto un plan de tools a utilizar,
|
||||
se procede a llamar las herramientas y agregar las respuestas al cognition prompt por ejemplo:
|
||||
-----vengo yo y te digo----- quiero entrar. te vas a dar cuenta por mi nombre de usuario que soy un empleado y que quiero registrar mi entrada. pero necesitas saber cual es mi id
|
||||
por lo tanto vas a llenar el cognition prompt con la siguiente informacion:
|
||||
- **Identidad del hablante**: "jose dario"
|
||||
- **Entender el mensaje**: "Quiero registrar mi entrada"
|
||||
- **Procesar la solicitud**: buscar empleado.search y usar el id para crear asistencias.createEntrada despues responder,
|
||||
|
||||
se ejecuta otra llamada a un llm para que usando esto se decida a ejecutar las herramientas necesarias y generar una respuesta al usuario.
|
||||
solo puede ejecutar una herramienta a la vez, en el cognition prompt se va guardando el estado de las herramientas ejecutadas y sus respuestas.
|
||||
cuando todas las herramientas hayan sido ejecutadas, se genera una respuesta final al usuario.
|
||||
|
||||
## Rol general
|
||||
Sos el *Agente de Planillas* del Núcleo. Tu trabajo es manejar, vía servidor MCP, las operaciones CRUD de las tablas **empleados**, **planillas**, **asistencias** y **tareas**.
|
||||
Respondés siempre en español, con mensajes breves y el tono casual de un colega hondureño (usá *vos* y expresiones locales).
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Reglas de interacción
|
||||
|
||||
### 1. Identidad del hablante
|
||||
- Usá los metadatos del mensaje para identificar quién escribe.
|
||||
- Si el usuario habla de “mí”, asumí que se refiere a su propio registro de *empleado* y confirmalo:
|
||||
|
||||
Ej: ¿Hablamos de tu usuario (ID 123) o de otra persona?
|
||||
|
||||
- Si menciona otro nombre/ID, verificá que exista; si no, devolvé error.
|
||||
|
||||
---
|
||||
|
||||
### 2. Tabla: asistencias
|
||||
- Al crear **entrada**, la fecha y hora es el momento actual.
|
||||
- Si ya hay una asistencia abierta hoy → respondé que ya fue registrada.
|
||||
- Al crear **salida**, también usá la hora actual.
|
||||
- Si no hay entrada abierta → indicá que primero debe marcar entrada.
|
||||
- Estado inicial siempre es "pendiente".
|
||||
- No permitás modificar registros que ya tienen entrada y salida.
|
||||
|
||||
---
|
||||
|
||||
### 3. Tabla: tareas
|
||||
- Cada tarea debe estar asociada a un *empleado válido*.
|
||||
- precio es opcional; si no se da, guardalo como 0.
|
||||
- Permití crear, listar, editar y borrar tareas sin restricciones.
|
||||
|
||||
---
|
||||
|
||||
### 4. Tabla: planillas
|
||||
- Agrupan asistencias y tareas de uno o varios empleados dentro de un rango fecha_desde → fecha_hasta.
|
||||
- Al crear:
|
||||
1. Validá que existan los empleados.
|
||||
2. Incluí tareas/asistencias del rango.
|
||||
3. Guardá con estado = "borrador".
|
||||
- Se pueden actualizar: título, fechas, estado.
|
||||
- Al cerrar una planilla se deben fijar los montos finales.
|
||||
|
||||
---
|
||||
|
||||
### 5. Tabla: empleados
|
||||
- Permití: alta, edición, baja lógica (activo = false) y consulta.
|
||||
- Antes de operar en otras tablas, validá que el empleado esté activo.
|
||||
|
||||
---
|
||||
|
||||
|
||||
`;
|
||||
@@ -12,29 +12,8 @@ export const systemPrompt = `
|
||||
- cuando sos activado, tenes que entender los mensajes del objeto 'conversation' desde el ultimo mensaje pues es el mas nuevo.
|
||||
no siempre ese mensaje contiene todo el contexto, por lo que debes buscar en los mensajes anteriores de la conversacion para entender el contexto completo.
|
||||
- entre los mensajes del objeto 'conversation' pueden haber mensajes tuyos, que respondiste en otra interaccion. recorda que podes aprovechar esta capacidad para hablar con vos mismo en el futuro
|
||||
- aparte del system prompt y del objeto 'conversation', tenes acceso a un cognition prompt donde se te va indicando que accion es la que estas realizando de tu proceso cognitivo.
|
||||
- vos tenes un cognition flow predefinido asi que tenes que conocerlo, entender en que parte estas y que accion tenes que realizar para sacar el mejor provecho.
|
||||
- el cognition flow va de esta forma:
|
||||
|
||||
## Cognition Flow
|
||||
se ejecuta una llamada a un llm para que analice el convo y genere estas respuestas:
|
||||
1. **Identificar al hablante**: ¿Quién está escribiendo? ¿Es un usuario conocido?
|
||||
${'variable respuestaIdentidadHablante'}
|
||||
2. **Entender el mensaje**: ¿Qué pregunta o solicitud se está haciendo?
|
||||
${'variable respuestaEntenderMensaje'}
|
||||
3. **Procesar la solicitud**: ¿que herramientas puedo llamar para lograr el objetivo?
|
||||
${'variable respuestaProcesarSolicitud'}
|
||||
4. **Responder al usuario**: una vez hayas llenado las primeras dos variables y provisto un plan de tools a utilizar,
|
||||
se procede a llamar las herramientas y agregar las respuestas al cognition prompt por ejemplo:
|
||||
-----vengo yo y te digo----- quiero entrar. te vas a dar cuenta por mi nombre de usuario que soy un empleado y que quiero registrar mi entrada. pero necesitas saber cual es mi id
|
||||
por lo tanto vas a llenar el cognition prompt con la siguiente informacion:
|
||||
- **Identidad del hablante**: "jose dario"
|
||||
- **Entender el mensaje**: "Quiero registrar mi entrada"
|
||||
- **Procesar la solicitud**: buscar empleado.search y usar el id para crear asistencias.createEntrada despues responder,
|
||||
|
||||
se ejecuta otra llamada a un llm para que usando esto se decida a ejecutar las herramientas necesarias y generar una respuesta al usuario.
|
||||
solo puede ejecutar una herramienta a la vez, en el cognition prompt se va guardando el estado de las herramientas ejecutadas y sus respuestas.
|
||||
cuando todas las herramientas hayan sido ejecutadas, se genera una respuesta final al usuario.
|
||||
- tenes la capacidad de llamar de manera secuencial a las herramientas del mcp planilla, eso significa que podes llamar una herramienta, esperar su respuesta y usar esa respuesta para llamar a la siguiente
|
||||
- la respuesta final siempre la tenes que dar hasta terminar de llamar a todas tus herramientas y obtener un resultado de cada una de ellas para luego usar eso para guiar tu respuesta final
|
||||
|
||||
## Rol general
|
||||
Sos el *Agente de Planillas* del Núcleo. Tu trabajo es manejar, vía servidor MCP, las operaciones CRUD de las tablas **empleados**, **planillas**, **asistencias** y **tareas**.
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"type": "module",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"dev": "nodemon src/index.js",
|
||||
"start": "node server.js"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -17,7 +17,7 @@ async function main() {
|
||||
app.use(express.json());
|
||||
|
||||
app.use((req, _res, next) => {
|
||||
console.log(`[HTTP] ${req.method} ${req.originalUrl}`);
|
||||
console.log(`[HTTP] ${req.method} ${req.originalUrl} ${req.statusCode} ${req.res.body}`);
|
||||
next();
|
||||
});
|
||||
|
||||
|
||||
@@ -103,6 +103,8 @@ export default function registerAsistencias(server) {
|
||||
);
|
||||
if (qs.toString() === "") qs.append("limit", "100");
|
||||
const asistencias = await fetchJSON(`/api/asistencias/search?${qs.toString()}`);
|
||||
console.log("tool terminada ", JSON.stringify(asistencias));
|
||||
|
||||
return { content: [{ type: "text", text: JSON.stringify(asistencias) }] };
|
||||
}
|
||||
);
|
||||
|
||||
101
mcp/package-lock.json
generated
101
mcp/package-lock.json
generated
@@ -11,6 +11,10 @@
|
||||
"@modelcontextprotocol/sdk": "^1.0.0",
|
||||
"express": "^5.1.0",
|
||||
"zod": "^3.24.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"node-cron": "^4.0.5",
|
||||
"prisma": "^6.8.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@modelcontextprotocol/sdk": {
|
||||
@@ -33,6 +37,60 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/config": {
|
||||
"version": "6.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.9.0.tgz",
|
||||
"integrity": "sha512-Wcfk8/lN3WRJd5w4jmNQkUwhUw0eksaU/+BlAJwPQKW10k0h0LC9PD/6TQFmqKVbHQL0vG2z266r0S1MPzzhbA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"jiti": "2.4.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/debug": {
|
||||
"version": "6.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.9.0.tgz",
|
||||
"integrity": "sha512-bFeur/qi/Q+Mqk4JdQ3R38upSYPebv5aOyD1RKywVD+rAMLtRkmTFn28ZuTtVOnZHEdtxnNOCH+bPIeSGz1+Fg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@prisma/engines": {
|
||||
"version": "6.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.9.0.tgz",
|
||||
"integrity": "sha512-im0X0bwDLA0244CDf8fuvnLuCQcBBdAGgr+ByvGfQY9wWl6EA+kRGwVk8ZIpG65rnlOwtaWIr/ZcEU5pNVvq9g==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@prisma/debug": "6.9.0",
|
||||
"@prisma/engines-version": "6.9.0-10.81e4af48011447c3cc503a190e86995b66d2a28e",
|
||||
"@prisma/fetch-engine": "6.9.0",
|
||||
"@prisma/get-platform": "6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/engines-version": {
|
||||
"version": "6.9.0-10.81e4af48011447c3cc503a190e86995b66d2a28e",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.9.0-10.81e4af48011447c3cc503a190e86995b66d2a28e.tgz",
|
||||
"integrity": "sha512-Qp9gMoBHgqhKlrvumZWujmuD7q4DV/gooEyPCLtbkc13EZdSz2RsGUJ5mHb3RJgAbk+dm6XenqG7obJEhXcJ6Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@prisma/fetch-engine": {
|
||||
"version": "6.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.9.0.tgz",
|
||||
"integrity": "sha512-PMKhJdl4fOdeE3J3NkcWZ+tf3W6rx3ht/rLU8w4SXFRcLhd5+3VcqY4Kslpdm8osca4ej3gTfB3+cSk5pGxgFg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@prisma/debug": "6.9.0",
|
||||
"@prisma/engines-version": "6.9.0-10.81e4af48011447c3cc503a190e86995b66d2a28e",
|
||||
"@prisma/get-platform": "6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@prisma/get-platform": {
|
||||
"version": "6.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.9.0.tgz",
|
||||
"integrity": "sha512-/B4n+5V1LI/1JQcHp+sUpyRT1bBgZVPHbsC4lt4/19Xp4jvNIVcq5KYNtQDk5e/ukTSjo9PZVAxxy9ieFtlpTQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@prisma/debug": "6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/accepts": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
|
||||
@@ -501,6 +559,15 @@
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
|
||||
},
|
||||
"node_modules/jiti": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
|
||||
"integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"jiti": "lib/jiti-cli.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
@@ -567,6 +634,15 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/node-cron": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/node-cron/-/node-cron-4.1.0.tgz",
|
||||
"integrity": "sha512-OS+3ORu+h03/haS6Di8Qr7CrVs4YaKZZOynZwQpyPZDnR3tqRbwJmuP2gVR16JfhLgyNlloAV1VTrrWlRogCFA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
@@ -630,6 +706,31 @@
|
||||
"node": ">=16.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prisma": {
|
||||
"version": "6.9.0",
|
||||
"resolved": "https://registry.npmjs.org/prisma/-/prisma-6.9.0.tgz",
|
||||
"integrity": "sha512-resJAwMyZREC/I40LF6FZ6rZTnlrlrYrb63oW37Gq+U+9xHwbyMSPJjKtM7VZf3gTO86t/Oyz+YeSXr3CmAY1Q==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@prisma/config": "6.9.0",
|
||||
"@prisma/engines": "6.9.0"
|
||||
},
|
||||
"bin": {
|
||||
"prisma": "build/index.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-addr": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||
|
||||
@@ -3,11 +3,16 @@
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "node index.js"
|
||||
"start": "node index.js",
|
||||
"dev": "nodemon src/index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/sdk": "^1.0.0",
|
||||
"express": "^5.1.0",
|
||||
"zod": "^3.24.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"node-cron": "^4.0.5",
|
||||
"prisma": "^6.8.2"
|
||||
}
|
||||
}
|
||||
|
||||
12
ui/package-lock.json
generated
12
ui/package-lock.json
generated
@@ -10,6 +10,7 @@
|
||||
"dependencies": {
|
||||
"@tailwindcss/vite": "^4.1.7",
|
||||
"axios": "^1.9.0",
|
||||
"dotenv": "^16.5.0",
|
||||
"pinia": "^3.0.2",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^4.5.1"
|
||||
@@ -1836,6 +1837,17 @@
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dotenv": {
|
||||
"version": "16.5.0",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz",
|
||||
"integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://dotenvx.com"
|
||||
}
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"dependencies": {
|
||||
"@tailwindcss/vite": "^4.1.7",
|
||||
"axios": "^1.9.0",
|
||||
"dotenv": "^16.5.0",
|
||||
"pinia": "^3.0.2",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^4.5.1"
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import axios from 'axios';
|
||||
// forzar subida
|
||||
|
||||
const baseURL = import.meta.env.API_BASE_URL || 'http://localhost:4000'
|
||||
// const baseURL = import.meta.env.API_BASE_URL || 'https://planilla.interno.com'
|
||||
console.log(baseURL);
|
||||
|
||||
const apiClient = axios.create({
|
||||
baseURL: 'https://planilla.interno.com', // Using the container name and API port
|
||||
baseURL,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user