@ssolis-ti/mcp-compra-agil 1.0.3 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/README.md +111 -23
  2. package/dist/api/compra-agil-client.d.ts +37 -2
  3. package/dist/api/compra-agil-client.d.ts.map +1 -1
  4. package/dist/api/compra-agil-client.js +76 -5
  5. package/dist/api/compra-agil-client.js.map +1 -1
  6. package/dist/index.js +32 -8
  7. package/dist/index.js.map +1 -1
  8. package/dist/reports/components.d.ts +59 -0
  9. package/dist/reports/components.d.ts.map +1 -0
  10. package/dist/reports/components.js +125 -0
  11. package/dist/reports/components.js.map +1 -0
  12. package/dist/reports/export.d.ts +27 -0
  13. package/dist/reports/export.d.ts.map +1 -0
  14. package/dist/reports/export.js +47 -0
  15. package/dist/reports/export.js.map +1 -0
  16. package/dist/reports/format.d.ts +24 -0
  17. package/dist/reports/format.d.ts.map +1 -0
  18. package/dist/reports/format.js +74 -0
  19. package/dist/reports/format.js.map +1 -0
  20. package/dist/reports/render.d.ts +18 -0
  21. package/dist/reports/render.d.ts.map +1 -0
  22. package/dist/reports/render.js +30 -0
  23. package/dist/reports/render.js.map +1 -0
  24. package/dist/reports/templates/radar-oportunidades.d.ts +41 -0
  25. package/dist/reports/templates/radar-oportunidades.d.ts.map +1 -0
  26. package/dist/reports/templates/radar-oportunidades.js +170 -0
  27. package/dist/reports/templates/radar-oportunidades.js.map +1 -0
  28. package/dist/reports/theme.d.ts +83 -0
  29. package/dist/reports/theme.d.ts.map +1 -0
  30. package/dist/reports/theme.js +284 -0
  31. package/dist/reports/theme.js.map +1 -0
  32. package/dist/resources/compras-template.d.ts.map +1 -1
  33. package/dist/resources/compras-template.js +2 -1
  34. package/dist/resources/compras-template.js.map +1 -1
  35. package/dist/resources/documentacion.d.ts.map +1 -1
  36. package/dist/resources/documentacion.js +5 -36
  37. package/dist/resources/documentacion.js.map +1 -1
  38. package/dist/resources/estados.d.ts.map +1 -1
  39. package/dist/resources/estados.js +24 -10
  40. package/dist/resources/estados.js.map +1 -1
  41. package/dist/services/monitor.js +38 -3
  42. package/dist/services/monitor.js.map +1 -1
  43. package/dist/tools/analizar-precios-mercado.d.ts +21 -0
  44. package/dist/tools/analizar-precios-mercado.d.ts.map +1 -0
  45. package/dist/tools/analizar-precios-mercado.js +217 -0
  46. package/dist/tools/analizar-precios-mercado.js.map +1 -0
  47. package/dist/tools/auditar-desiertas.d.ts.map +1 -1
  48. package/dist/tools/auditar-desiertas.js +66 -48
  49. package/dist/tools/auditar-desiertas.js.map +1 -1
  50. package/dist/tools/buscar-compras.d.ts.map +1 -1
  51. package/dist/tools/buscar-compras.js +2 -1
  52. package/dist/tools/buscar-compras.js.map +1 -1
  53. package/dist/tools/detalle-compra.d.ts.map +1 -1
  54. package/dist/tools/detalle-compra.js +6 -5
  55. package/dist/tools/detalle-compra.js.map +1 -1
  56. package/dist/tools/detalle-oc.js +6 -6
  57. package/dist/tools/detalle-oc.js.map +1 -1
  58. package/dist/tools/documentos.d.ts.map +1 -1
  59. package/dist/tools/documentos.js +75 -81
  60. package/dist/tools/documentos.js.map +1 -1
  61. package/dist/tools/estadisticas-uso.d.ts.map +1 -1
  62. package/dist/tools/estadisticas-uso.js +12 -2
  63. package/dist/tools/estadisticas-uso.js.map +1 -1
  64. package/dist/tools/generar-borrador.d.ts +25 -1
  65. package/dist/tools/generar-borrador.d.ts.map +1 -1
  66. package/dist/tools/generar-borrador.js +111 -82
  67. package/dist/tools/generar-borrador.js.map +1 -1
  68. package/dist/tools/generar-informe.d.ts +13 -0
  69. package/dist/tools/generar-informe.d.ts.map +1 -0
  70. package/dist/tools/generar-informe.js +111 -0
  71. package/dist/tools/generar-informe.js.map +1 -0
  72. package/dist/tools/monitorear-cambios.d.ts +32 -2
  73. package/dist/tools/monitorear-cambios.d.ts.map +1 -1
  74. package/dist/tools/monitorear-cambios.js +79 -10
  75. package/dist/tools/monitorear-cambios.js.map +1 -1
  76. package/dist/tools/radar-oportunidades.d.ts +42 -1
  77. package/dist/tools/radar-oportunidades.d.ts.map +1 -1
  78. package/dist/tools/radar-oportunidades.js +123 -103
  79. package/dist/tools/radar-oportunidades.js.map +1 -1
  80. package/dist/tools/recomendar-precio.d.ts +13 -0
  81. package/dist/tools/recomendar-precio.d.ts.map +1 -1
  82. package/dist/tools/recomendar-precio.js +53 -57
  83. package/dist/tools/recomendar-precio.js.map +1 -1
  84. package/dist/tools/verificar-oc.d.ts.map +1 -1
  85. package/dist/tools/verificar-oc.js +36 -8
  86. package/dist/tools/verificar-oc.js.map +1 -1
  87. package/dist/tools/verificar-ticket.d.ts +13 -0
  88. package/dist/tools/verificar-ticket.d.ts.map +1 -0
  89. package/dist/tools/verificar-ticket.js +79 -0
  90. package/dist/tools/verificar-ticket.js.map +1 -0
  91. package/dist/utils/cache.d.ts +53 -0
  92. package/dist/utils/cache.d.ts.map +1 -0
  93. package/dist/utils/cache.js +131 -0
  94. package/dist/utils/cache.js.map +1 -0
  95. package/dist/utils/doc-search.d.ts +52 -0
  96. package/dist/utils/doc-search.d.ts.map +1 -0
  97. package/dist/utils/doc-search.js +97 -0
  98. package/dist/utils/doc-search.js.map +1 -0
  99. package/dist/utils/docs-locator.d.ts +41 -0
  100. package/dist/utils/docs-locator.d.ts.map +1 -0
  101. package/dist/utils/docs-locator.js +82 -0
  102. package/dist/utils/docs-locator.js.map +1 -0
  103. package/dist/utils/error-handler.d.ts.map +1 -1
  104. package/dist/utils/error-handler.js +8 -7
  105. package/dist/utils/error-handler.js.map +1 -1
  106. package/dist/utils/logger.d.ts.map +1 -1
  107. package/dist/utils/logger.js +9 -6
  108. package/dist/utils/logger.js.map +1 -1
  109. package/dist/utils/quotation.d.ts +71 -0
  110. package/dist/utils/quotation.d.ts.map +1 -0
  111. package/dist/utils/quotation.js +140 -0
  112. package/dist/utils/quotation.js.map +1 -0
  113. package/dist/utils/rate-limiter.d.ts +44 -2
  114. package/dist/utils/rate-limiter.d.ts.map +1 -1
  115. package/dist/utils/rate-limiter.js +125 -13
  116. package/dist/utils/rate-limiter.js.map +1 -1
  117. package/dist/utils/redact.d.ts +48 -0
  118. package/dist/utils/redact.d.ts.map +1 -0
  119. package/dist/utils/redact.js +100 -0
  120. package/dist/utils/redact.js.map +1 -0
  121. package/package.json +55 -53
@@ -1,6 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { CompraAgilApiError } from '../utils/error-handler.js';
3
3
  import { logger } from '../utils/logger.js';
4
+ import { safeError } from '../utils/redact.js';
4
5
  const TOOL_NAME = 'radar_oportunidades_calientes';
5
6
  const TOOL_DESCRIPTION = `Escanea, califica y clasifica de forma priorizada los procesos de Compra Ágil activos (publicados).
6
7
  Utiliza una fórmula ponderada (Hot Score) basada en la falta de oferentes, el presupuesto disponible y las horas restantes de cierre para destacar los llamados más convenientes y fáciles de ganar.`;
@@ -9,23 +10,131 @@ const inputSchema = {
9
10
  q: z.string().optional().describe('Término de búsqueda opcional para acotar a un rubro o producto específico (ej: "licencias").'),
10
11
  presupuesto_minimo: z.number().optional().describe('Filtrar solo procesos con presupuesto disponible mayor o igual a este monto en CLP.'),
11
12
  limite_resultados: z.number().min(1).max(20).default(10).optional().describe('Cantidad máxima de oportunidades destacadas a retornar (1-20, default 10).'),
13
+ max_paginas: z.number().min(1).max(10).default(3).optional().describe('Cuántas páginas de 50 resultados escanear antes de rankear (1-10, default 3 = hasta 150 procesos). Más páginas = más cobertura pero más consumo de cuota.'),
12
14
  };
15
+ /**
16
+ * Calcula el "Hot Score" de una oportunidad de forma pura (sin efectos secundarios).
17
+ * Retorna null si el proceso debe omitirse (ya cerrado o bajo el presupuesto mínimo).
18
+ * Ponderación: baja competencia (máx 50) + urgencia (máx 30) + presupuesto (máx 20) + facilidad (máx 5).
19
+ */
20
+ export function evaluarOportunidad(item, now, minBudget = 0) {
21
+ const budget = item.montos?.monto_disponible_clp || item.montos?.monto_disponible || 0;
22
+ if (budget < minBudget)
23
+ return null;
24
+ let hoursLeft = 0;
25
+ if (item.fechas?.fecha_cierre) {
26
+ const cierreTime = new Date(item.fechas.fecha_cierre).getTime();
27
+ hoursLeft = (cierreTime - now) / (1000 * 60 * 60);
28
+ }
29
+ if (hoursLeft <= 0)
30
+ return null;
31
+ let score = 0;
32
+ const factors = [];
33
+ // Factor 1: Baja Competencia — Máx 50 pts
34
+ const bids = item.resumen?.total_ofertas_recibidas ?? 0;
35
+ if (bids === 0) {
36
+ score += 50;
37
+ factors.push('Sin oferentes activos (+50 pts)');
38
+ }
39
+ else if (bids === 1) {
40
+ score += 30;
41
+ factors.push('Baja competencia: solo 1 oferente (+30 pts)');
42
+ }
43
+ else if (bids === 2) {
44
+ score += 15;
45
+ factors.push('Competencia moderada: 2 oferentes (+15 pts)');
46
+ }
47
+ // Factor 2: Urgencia del Cierre — Máx 30 pts
48
+ if (hoursLeft <= 4) {
49
+ score += 30;
50
+ factors.push('Urgencia crítica: cierra en menos de 4 horas (+30 pts)');
51
+ }
52
+ else if (hoursLeft <= 12) {
53
+ score += 20;
54
+ factors.push('Cierre inminente: cierra en menos de 12 horas (+20 pts)');
55
+ }
56
+ else if (hoursLeft <= 24) {
57
+ score += 10;
58
+ factors.push('Cierre cercano: cierra en menos de 24 horas (+10 pts)');
59
+ }
60
+ // Factor 3: Tamaño de Presupuesto — Máx 20 pts
61
+ if (budget >= 5000000) {
62
+ score += 20;
63
+ factors.push('Presupuesto de alto valor (>= $5.000.000 CLP) (+20 pts)');
64
+ }
65
+ else if (budget >= 2000000) {
66
+ score += 15;
67
+ factors.push('Presupuesto medio-alto (>= $2.000.000 CLP) (+15 pts)');
68
+ }
69
+ else if (budget >= 500000) {
70
+ score += 10;
71
+ factors.push('Presupuesto medio (>= $500.000 CLP) (+10 pts)');
72
+ }
73
+ else {
74
+ score += 5;
75
+ factors.push('Presupuesto bajo (< $500.000 CLP) (+5 pts)');
76
+ }
77
+ // Factor 4: Facilidad de Postulación — Máx 5 pts
78
+ const docsCount = item.documentos?.length || 0;
79
+ if (docsCount === 0) {
80
+ score += 5;
81
+ factors.push('Sin documentos adjuntos (postulación rápida sin leer bases) (+5 pts)');
82
+ }
83
+ return {
84
+ codigo: item.codigo,
85
+ nombre: item.nombre,
86
+ organismo: item.institucion?.organismo_comprador || 'No especificado',
87
+ region: item.institucion?.nombre_region || 'No especificada',
88
+ presupuesto_disponible: budget,
89
+ ofertas_recibidas: bids,
90
+ horas_restantes: Math.round(hoursLeft * 10) / 10,
91
+ fecha_cierre: item.fechas?.fecha_cierre,
92
+ puntuacion_caliente: score,
93
+ factores_calificacion: factors,
94
+ };
95
+ }
96
+ /**
97
+ * Recolecta y rankea las oportunidades del radar.
98
+ *
99
+ * Función pura de datos (sin formato de salida): la comparten la tool
100
+ * `radar_oportunidades_calientes` (que emite JSON para el LLM) y el informe
101
+ * HTML/PDF, garantizando que ambos muestren exactamente lo mismo.
102
+ */
103
+ export async function recolectarDatosRadar(client, params, now = Date.now()) {
104
+ const maxPaginas = params.max_paginas || 3;
105
+ logger.info(`radar: escaneando procesos activos (hasta ${maxPaginas} pág.) region="${params.region || 'Todas'}" q="${params.q || 'Todos'}"`);
106
+ // Auto-paginación: escanear varias páginas para no perder oportunidades en páginas 2+
107
+ const items = await client.buscarTodo({
108
+ estado: 'publicada',
109
+ region: params.region || undefined,
110
+ q: params.q || undefined,
111
+ tamano_pagina: 50,
112
+ }, maxPaginas);
113
+ const minBudget = params.presupuesto_minimo || 0;
114
+ const opportunities = [];
115
+ for (const item of items) {
116
+ const evaluada = evaluarOportunidad(item, now, minBudget);
117
+ if (evaluada)
118
+ opportunities.push(evaluada);
119
+ }
120
+ // Ordenar descendentemente por puntuación caliente
121
+ opportunities.sort((a, b) => b.puntuacion_caliente - a.puntuacion_caliente);
122
+ const limite = params.limite_resultados || 10;
123
+ return {
124
+ oportunidades: opportunities.slice(0, limite),
125
+ totalAnalizadas: opportunities.length,
126
+ limite,
127
+ paginasEscaneadas: maxPaginas,
128
+ };
129
+ }
13
130
  export function registerRadarOportunidades(server, client) {
14
131
  server.registerTool(TOOL_NAME, {
15
132
  description: TOOL_DESCRIPTION,
16
133
  inputSchema: inputSchema,
17
134
  }, async (args) => {
18
135
  try {
19
- const queryParams = {
20
- estado: 'publicada',
21
- region: args.region || undefined,
22
- q: args.q || undefined,
23
- tamano_pagina: 50, // Obtener un lote amplio de 50 para poder rankear
24
- numero_pagina: 1,
25
- };
26
- logger.info(`radar_oportunidades_calientes: Escaneando procesos activos para region="${args.region || 'Todas'}" q="${args.q || 'Todos'}"`);
27
- const searchResponse = await client.buscar(queryParams);
28
- if (!searchResponse.items || searchResponse.items.length === 0) {
136
+ const datos = await recolectarDatosRadar(client, args);
137
+ if (datos.totalAnalizadas === 0) {
29
138
  return {
30
139
  content: [{
31
140
  type: 'text',
@@ -33,99 +142,10 @@ export function registerRadarOportunidades(server, client) {
33
142
  }],
34
143
  };
35
144
  }
36
- const now = Date.now();
37
- const opportunities = [];
38
- const minBudget = args.presupuesto_minimo || 0;
39
- for (const item of searchResponse.items) {
40
- const budget = item.montos?.monto_disponible_clp || item.montos?.monto_disponible || 0;
41
- // Filtrar por presupuesto mínimo si corresponde
42
- if (budget < minBudget) {
43
- continue;
44
- }
45
- // Calcular tiempo restante en horas
46
- let hoursLeft = 0;
47
- if (item.fechas?.fecha_cierre) {
48
- const cierreTime = new Date(item.fechas.fecha_cierre).getTime();
49
- hoursLeft = (cierreTime - now) / (1000 * 60 * 60);
50
- }
51
- // Omitir procesos que ya cerraron o están en negativo por zona horaria
52
- if (hoursLeft <= 0) {
53
- continue;
54
- }
55
- let score = 0;
56
- const factors = [];
57
- // Factor 1: Baja Competencia (total_ofertas_recibidas) - Máx 50 pts
58
- const bids = item.resumen?.total_ofertas_recibidas ?? 0;
59
- if (bids === 0) {
60
- score += 50;
61
- factors.push('Sin oferentes activos (+50 pts)');
62
- }
63
- else if (bids === 1) {
64
- score += 30;
65
- factors.push('Baja competencia: solo 1 oferente (+30 pts)');
66
- }
67
- else if (bids === 2) {
68
- score += 15;
69
- factors.push('Competencia moderada: 2 oferentes (+15 pts)');
70
- }
71
- // Factor 2: Urgencia del Cierre (horas restantes) - Máx 30 pts
72
- if (hoursLeft <= 4) {
73
- score += 30;
74
- factors.push('Urgencia crítica: cierra en menos de 4 horas (+30 pts)');
75
- }
76
- else if (hoursLeft <= 12) {
77
- score += 20;
78
- factors.push('Cierre inminente: cierra en menos de 12 horas (+20 pts)');
79
- }
80
- else if (hoursLeft <= 24) {
81
- score += 10;
82
- factors.push('Cierre cercano: cierra en menos de 24 horas (+10 pts)');
83
- }
84
- // Factor 3: Tamaño de Presupuesto - Máx 20 pts
85
- if (budget >= 5000000) {
86
- score += 20;
87
- factors.push('Presupuesto de alto valor (>= $5.000.000 CLP) (+20 pts)');
88
- }
89
- else if (budget >= 2000000) {
90
- score += 15;
91
- factors.push('Presupuesto medio-alto (>= $2.000.000 CLP) (+15 pts)');
92
- }
93
- else if (budget >= 500000) {
94
- score += 10;
95
- factors.push('Presupuesto medio (>= $500.000 CLP) (+10 pts)');
96
- }
97
- else {
98
- score += 5;
99
- factors.push('Presupuesto bajo (< $500.000 CLP) (+5 pts)');
100
- }
101
- // Factor 4: Facilidad de Postulación - Máx 5 pts
102
- const docsCount = item.documentos?.length || 0;
103
- if (docsCount === 0) {
104
- score += 5;
105
- factors.push('Sin documentos adjuntos (postulación rápida sin leer bases) (+5 pts)');
106
- }
107
- opportunities.push({
108
- codigo: item.codigo,
109
- nombre: item.nombre,
110
- organismo: item.institucion?.organismo_comprador || 'No especificado',
111
- region: item.institucion?.nombre_region || 'No especificada',
112
- presupuesto_disponible: budget,
113
- ofertas_recibidas: bids,
114
- horas_restantes: Math.round(hoursLeft * 10) / 10,
115
- fecha_cierre: item.fechas?.fecha_cierre,
116
- puntuacion_caliente: score,
117
- factores_calificacion: factors,
118
- });
119
- }
120
- // Ordenar descendentemente por puntuación caliente
121
- opportunities.sort((a, b) => b.puntuacion_caliente - a.puntuacion_caliente);
122
- // Aplicar límite
123
- const limit = args.limite_resultados || 10;
124
- const rankedOpportunities = opportunities.slice(0, limit);
125
145
  const result = {
126
- total_oportunidades_analizadas: opportunities.length,
127
- radar_limite_resultados: limit,
128
- oportunidades_calientes: rankedOpportunities,
146
+ total_oportunidades_analizadas: datos.totalAnalizadas,
147
+ radar_limite_resultados: datos.limite,
148
+ oportunidades_calientes: datos.oportunidades,
129
149
  };
130
150
  return {
131
151
  content: [{
@@ -137,7 +157,7 @@ export function registerRadarOportunidades(server, client) {
137
157
  catch (error) {
138
158
  const message = error instanceof CompraAgilApiError
139
159
  ? error.actionableMessage
140
- : `Error inesperado en radar de oportunidades: ${String(error)}`;
160
+ : `Error inesperado en radar de oportunidades: ${safeError(error)}`;
141
161
  return {
142
162
  content: [{ type: 'text', text: message }],
143
163
  isError: true,
@@ -1 +1 @@
1
- {"version":3,"file":"radar-oportunidades.js","sourceRoot":"","sources":["../../src/tools/radar-oportunidades.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"radar-oportunidades.js","sourceRoot":"","sources":["../../src/tools/radar-oportunidades.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,17 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { CompraAgilClient } from '../api/compra-agil-client.js';
3
3
  export declare function registerRecomendarPrecio(server: McpServer, client: CompraAgilClient): void;
4
+ interface EstadisticasPrecio {
5
+ muestras: number;
6
+ minimo: number;
7
+ maximo: number;
8
+ promedio: number;
9
+ mediana: number;
10
+ }
11
+ /**
12
+ * Calcula min/max/promedio/mediana de una serie de precios.
13
+ * Retorna null si la serie está vacía (para poder distinguir "sin datos").
14
+ */
15
+ export declare function calcularEstadisticas(valores: number[]): EstadisticasPrecio | null;
16
+ export {};
4
17
  //# sourceMappingURL=recomendar-precio.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"recomendar-precio.d.ts","sourceRoot":"","sources":["../../src/tools/recomendar-precio.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAiBhE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CA0L1F"}
1
+ {"version":3,"file":"recomendar-precio.d.ts","sourceRoot":"","sources":["../../src/tools/recomendar-precio.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAoBhE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAgK1F;AAED,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,kBAAkB,GAAG,IAAI,CAWjF"}
@@ -1,10 +1,13 @@
1
1
  import { z } from 'zod';
2
2
  import { CompraAgilApiError } from '../utils/error-handler.js';
3
3
  import { logger } from '../utils/logger.js';
4
+ import { esGanador, extraerPrecioUnitario, extraerMontoNeto } from '../utils/quotation.js';
5
+ import { safeError } from '../utils/redact.js';
4
6
  const TOOL_NAME = 'recomendar_precio_ganador';
5
- const TOOL_DESCRIPTION = `Analiza procesos históricos similares de Compra Ágil que ya fueron cerrados y adjudicados para estimar y sugerir un precio unitario o total óptimo y competitivo para postular.
7
+ const TOOL_DESCRIPTION = `Analiza procesos históricos similares de Compra Ágil que ya fueron cerrados y adjudicados para estimar y sugerir un precio competitivo para postular.
6
8
  Admite ingresar el código de una compra activa para extraer automáticamente las palabras clave o un término de búsqueda genérico.
7
- Nota: Realiza consultas en paralelo acotadas por el rate limiter.`;
9
+ Distingue entre precio UNITARIO (comparable directamente) y monto NETO total adjudicado, reportando cada estadística por separado.
10
+ Nota: Las consultas históricas se realizan de forma secuencial y respetan el límite de tasa (throttle) interno para no agotar la cuota diaria de la API.`;
8
11
  const inputSchema = {
9
12
  codigo_compra: z.string().optional().describe('Código de la Compra Ágil activa para analizar (ej: "1057539-228-COT26"). Opcional si se especifica "q".'),
10
13
  q: z.string().optional().describe('Término de búsqueda de producto/servicio a cotizar (ej: "resmas papel", "soporte computadores"). Opcional si se especifica "codigo_compra".'),
@@ -65,61 +68,43 @@ export function registerRecomendarPrecio(server, client) {
65
68
  }],
66
69
  };
67
70
  }
68
- // 3. Consultar en paralelo (acotado por el limitador interno de la clase client) los detalles para obtener el ganador
69
- const prices = [];
71
+ // 3. Consultar los detalles (secuencial, respetando el throttle del client) para obtener el ganador.
72
+ // IMPORTANTE (C2): se mantienen DOS series separadas — precios unitarios y montos netos totales —
73
+ // porque no son comparables entre sí y mezclarlos corrompe las estadísticas.
74
+ const unitPrices = [];
75
+ const totalPrices = [];
70
76
  const processedItems = [];
71
77
  const itemsToProcess = searchResponse.items.slice(0, limit);
72
78
  logger.info(`recomendar_precio_ganador: Analizando detalles de ${itemsToProcess.length} procesos adjudicados`);
73
79
  for (const item of itemsToProcess) {
74
80
  try {
75
81
  const detail = await client.detalle(item.codigo);
76
- // Buscar al adjudicado/ganador
77
- const winner = detail.proveedores_cotizando?.find(prov => {
78
- if (prov.proveedor_seleccionado === true || prov.proveedor_seleccionado === 1)
79
- return true;
80
- if (prov.seleccion && prov.seleccion.proveedor_seleccionado === true)
81
- return true;
82
- return false;
83
- });
82
+ // Buscar al adjudicado/ganador con la heurística centralizada (C1)
83
+ const winner = detail.proveedores_cotizando?.find(esGanador);
84
84
  if (winner) {
85
- const totalNeto = winner.valor_neto || winner.monto_total || 0;
86
- let unitPrice = null;
87
- // Intentar extraer el precio unitario del producto cotizado
88
- if (winner.productos_cotizados && winner.productos_cotizados.length === 1) {
89
- unitPrice = winner.productos_cotizados[0].precio_unitario;
90
- }
91
- else if (winner.productos_cotizados && winner.productos_cotizados.length > 1) {
92
- // Buscar el producto cotizado que más coincida con la keyword original
93
- const matchedProd = winner.productos_cotizados.find(p => p.nombre_producto.toLowerCase().includes(keyword.toLowerCase()));
94
- if (matchedProd) {
95
- unitPrice = matchedProd.precio_unitario;
96
- }
97
- else {
98
- // Fallback: usar el precio del primer item
99
- unitPrice = winner.productos_cotizados[0].precio_unitario;
100
- }
101
- }
102
- const priceValue = unitPrice || totalNeto;
103
- if (priceValue > 0) {
104
- prices.push(priceValue);
105
- }
85
+ const unitPrice = extraerPrecioUnitario(winner, keyword);
86
+ const totalNeto = extraerMontoNeto(winner);
87
+ if (unitPrice !== null)
88
+ unitPrices.push(unitPrice);
89
+ if (totalNeto !== null)
90
+ totalPrices.push(totalNeto);
106
91
  processedItems.push({
107
92
  codigo: item.codigo,
108
93
  institucion: item.institucion.organismo_comprador,
109
94
  fecha_cierre: item.fechas.fecha_cierre,
110
95
  ganador: winner.razon_social,
111
96
  es_emt: winner.es_emt,
112
- monto_total_adjudicado: winner.monto_total,
97
+ monto_neto_adjudicado: totalNeto,
113
98
  precio_unitario_adjudicado: unitPrice,
114
99
  criterio_seleccion: winner.seleccion?.criterio_seleccion || 'No especificado',
115
100
  });
116
101
  }
117
102
  }
118
103
  catch (detailError) {
119
- logger.warn(`recomendar_precio_ganador: Error al consultar detalle de ${item.codigo}: ${String(detailError)}`);
104
+ logger.warn(`recomendar_precio_ganador: Error al consultar detalle de ${item.codigo}: ${safeError(detailError)}`);
120
105
  }
121
106
  }
122
- if (prices.length === 0) {
107
+ if (unitPrices.length === 0 && totalPrices.length === 0) {
123
108
  return {
124
109
  content: [{
125
110
  type: 'text',
@@ -127,31 +112,25 @@ export function registerRecomendarPrecio(server, client) {
127
112
  }],
128
113
  };
129
114
  }
130
- // 4. Calcular estadísticas
131
- prices.sort((a, b) => a - b);
132
- const min = prices[0];
133
- const max = prices[prices.length - 1];
134
- const sum = prices.reduce((acc, val) => acc + val, 0);
135
- const avg = Math.round(sum / prices.length);
136
- // Mediana
137
- const mid = Math.floor(prices.length / 2);
138
- const median = prices.length % 2 !== 0 ? prices[mid] : Math.round((prices[mid - 1] + prices[mid]) / 2);
139
- // 5. Sugerir precio competitivo (5% por debajo del promedio como referencia competitiva, acotada por el mínimo)
140
- let recommended = Math.round(avg * 0.95);
141
- if (recommended < min) {
142
- recommended = min;
115
+ // 4. Calcular estadísticas por serie. Se prioriza la serie de precios UNITARIOS
116
+ // para la recomendación (comparable directamente); si no hay, se usa el monto neto.
117
+ const statsUnitarios = calcularEstadisticas(unitPrices);
118
+ const statsTotales = calcularEstadisticas(totalPrices);
119
+ const baseStats = statsUnitarios ?? statsTotales;
120
+ const baseTipo = statsUnitarios ? 'precio_unitario' : 'monto_neto_total';
121
+ // 5. Sugerir precio competitivo (5% por debajo del promedio, acotado por el mínimo)
122
+ let recommended = Math.round(baseStats.promedio * 0.95);
123
+ if (recommended < baseStats.minimo) {
124
+ recommended = baseStats.minimo;
143
125
  }
144
126
  const result = {
145
127
  proceso_activo: targetProductDetail || undefined,
146
128
  termino_clave_utilizado: keyword,
147
129
  region_analisis: region ? `Región ${region}` : 'Todas las regiones',
148
- procesos_analizados_exitosamente: prices.length,
149
- estadisticas_precios: {
150
- minimo_historico: min,
151
- maximo_historico: max,
152
- promedio_historico: avg,
153
- mediana_historica: median,
154
- },
130
+ procesos_adjudicados_analizados: processedItems.length,
131
+ estadisticas_precio_unitario: statsUnitarios,
132
+ estadisticas_monto_neto_total: statsTotales,
133
+ base_de_la_recomendacion: baseTipo,
155
134
  sugerencia_de_precio_competitivo: recommended,
156
135
  rango_sugerido: {
157
136
  min: Math.round(recommended * 0.95),
@@ -169,7 +148,7 @@ export function registerRecomendarPrecio(server, client) {
169
148
  catch (error) {
170
149
  const message = error instanceof CompraAgilApiError
171
150
  ? error.actionableMessage
172
- : `Error inesperado al recomendar precio: ${String(error)}`;
151
+ : `Error inesperado al recomendar precio: ${safeError(error)}`;
173
152
  return {
174
153
  content: [{ type: 'text', text: message }],
175
154
  isError: true,
@@ -177,4 +156,21 @@ export function registerRecomendarPrecio(server, client) {
177
156
  }
178
157
  });
179
158
  }
159
+ /**
160
+ * Calcula min/max/promedio/mediana de una serie de precios.
161
+ * Retorna null si la serie está vacía (para poder distinguir "sin datos").
162
+ */
163
+ export function calcularEstadisticas(valores) {
164
+ if (!valores || valores.length === 0)
165
+ return null;
166
+ const sorted = [...valores].sort((a, b) => a - b);
167
+ const min = sorted[0];
168
+ const max = sorted[sorted.length - 1];
169
+ const avg = Math.round(sorted.reduce((acc, v) => acc + v, 0) / sorted.length);
170
+ const mid = Math.floor(sorted.length / 2);
171
+ const median = sorted.length % 2 !== 0
172
+ ? sorted[mid]
173
+ : Math.round((sorted[mid - 1] + sorted[mid]) / 2);
174
+ return { muestras: sorted.length, minimo: min, maximo: max, promedio: avg, mediana: median };
175
+ }
180
176
  //# sourceMappingURL=recomendar-precio.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"recomendar-precio.js","sourceRoot":"","sources":["../../src/tools/recomendar-precio.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"recomendar-precio.js","sourceRoot":"","sources":["../../src/tools/recomendar-precio.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"verificar-oc.d.ts","sourceRoot":"","sources":["../../src/tools/verificar-oc.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAgBhE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CA+ErF"}
1
+ {"version":3,"file":"verificar-oc.d.ts","sourceRoot":"","sources":["../../src/tools/verificar-oc.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAkBhE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CA0GrF"}
@@ -10,10 +10,12 @@
10
10
  import { z } from 'zod';
11
11
  import { CompraAgilApiError } from '../utils/error-handler.js';
12
12
  import { logger } from '../utils/logger.js';
13
+ import { esGanador } from '../utils/quotation.js';
14
+ import { safeError } from '../utils/redact.js';
13
15
  const TOOL_NAME = 'verificar_orden_compra';
14
- const TOOL_DESCRIPTION = `Verifica si una Compra Ágil específica ya tiene una Orden de Compra (OC) emitida.
15
- IMPORTANTE: El estado "oc_emitida" de la API NO funciona en la práctica. Esta herramienta resuelve esa limitación
16
- consultando el detalle del proceso y cruzando con la API de Órdenes de Compra de Mercado Público si existe un id_orden_compra.`;
16
+ const TOOL_DESCRIPTION = `Informa si una Compra Ágil tiene Orden de Compra emitida, leyendo id_orden_compra del detalle.
17
+ ⚠ LIMITACIÓN VERIFICADA (julio 2026, re-confirmada en septiembre): en 45 procesos inspeccionados NINGUNO traía id_orden_compra, y el filtro "proveedor_seleccionado" devuelve 0 resultados. La API de Compra Ágil no publica adjudicaciones. Por eso esta herramienta NO consulta la API por su cuenta —sería gastar cuota para responder "no puedo saberlo"—: reutiliza el detalle si ya se pidió con "obtener_detalle_compra", y en cualquier caso indica cómo confirmarlo en la ficha pública.
18
+ Un "sin OC" NO prueba que la OC no exista: significa que la API no la expone.`;
17
19
  const inputSchema = {
18
20
  codigo: z.string().describe('Código único de la Compra Ágil a verificar. Formato: XXXXXX-YYY-COTXX. Ej: "1057539-228-COT26".'),
19
21
  };
@@ -23,7 +25,33 @@ export function registerVerificarOC(server, client) {
23
25
  inputSchema: inputSchema,
24
26
  }, async (args) => {
25
27
  try {
26
- const detalle = await client.detalle(args.codigo);
28
+ // ⚠ NO se consulta la API si el detalle no está ya en caché.
29
+ // Esta herramienta gastaba una consulta de cuota para responder algo
30
+ // que la API estructuralmente no publica: en 45 procesos inspeccionados
31
+ // más las verificaciones de septiembre 2026, NINGUNO trajo
32
+ // id_orden_compra. Pagar cuota por un "no puedo saberlo" garantizado
33
+ // es el peor negocio posible cuando el balde de tokens es escaso.
34
+ //
35
+ // Si el detalle ya se pagó antes (flujo natural: obtener_detalle_compra
36
+ // y luego preguntar por la OC), se aprovecha y la respuesta va completa
37
+ // sin costo. Si no, se responde igual con la explicación y la ficha.
38
+ const detalle = client.detalleEnCache(args.codigo);
39
+ if (!detalle) {
40
+ return {
41
+ content: [{
42
+ type: 'text',
43
+ text: JSON.stringify({
44
+ codigo: args.codigo,
45
+ verificacion_oc: {
46
+ tiene_orden_compra: null,
47
+ motivo: 'No se consultó la API a propósito, para no gastar cuota en una respuesta que se conoce de antemano: la API de Compra Ágil no publica adjudicaciones ni órdenes de compra (0 de 45 procesos inspeccionados traían id_orden_compra, re-verificado en septiembre de 2026).',
48
+ como_confirmarlo: `Abre la ficha pública del proceso, que sí muestra el estado real: https://buscador.mercadopublico.cl/ficha?code=${args.codigo}`,
49
+ si_quieres_los_datos_del_proceso: 'Llama primero a "obtener_detalle_compra"; después esta herramienta reutiliza ese detalle sin costo adicional y te informa lo que la API sí trae.',
50
+ },
51
+ }, null, 2),
52
+ }],
53
+ };
54
+ }
27
55
  const idOrdenCompra = detalle.id_orden_compra ?? detalle.orden_compra?.id_orden_compra ?? null;
28
56
  const idOc = detalle.orden_compra?.id_oc ?? null;
29
57
  const tieneOC = idOrdenCompra !== null && idOrdenCompra !== undefined;
@@ -45,7 +73,7 @@ export function registerVerificarOC(server, client) {
45
73
  }
46
74
  }
47
75
  catch (e) {
48
- logger.warn(`No se pudo obtener el detalle de la OC ${idOrdenCompra} desde la API: ${String(e)}`);
76
+ logger.warn(`No se pudo obtener el detalle de la OC ${idOrdenCompra} desde la API: ${safeError(e)}`);
49
77
  }
50
78
  }
51
79
  const result = {
@@ -62,10 +90,10 @@ export function registerVerificarOC(server, client) {
62
90
  detalle_orden: detalleOCInfo,
63
91
  nota: tieneOC
64
92
  ? `La OC fue emitida. Código: ${detalleOCInfo?.codigo_oc ?? 'Desconocido'}. Usa la herramienta obtener_detalle_orden_compra para profundizar.`
65
- : 'No se ha emitido una Orden de Compra para esta Compra Ágil aún.',
93
+ : `La API no reporta Orden de Compra para este proceso (id_orden_compra = null). ⚠ Ojo: esto NO prueba que la OC no exista. Se verificó que la API de Compra Ágil no está publicando adjudicaciones (45 procesos inspeccionados, 0 con id_orden_compra). Para confirmarlo consulta la ficha pública: https://buscador.mercadopublico.cl/ficha?code=${detalle.codigo}`,
66
94
  },
67
95
  proveedor_seleccionado: detalle.proveedores_cotizando
68
- .filter((p) => p.proveedor_seleccionado === 1 || p.proveedor_seleccionado === true || p.seleccion?.proveedor_seleccionado === true || p.estado_por_comprador === '1')
96
+ .filter(esGanador)
69
97
  .map((p) => ({
70
98
  rut: p.rut_proveedor,
71
99
  razon_social: p.razon_social,
@@ -83,7 +111,7 @@ export function registerVerificarOC(server, client) {
83
111
  catch (error) {
84
112
  const message = error instanceof CompraAgilApiError
85
113
  ? error.actionableMessage
86
- : `Error inesperado: ${String(error)}`;
114
+ : `Error inesperado: ${safeError(error)}`;
87
115
  return {
88
116
  content: [{ type: 'text', text: message }],
89
117
  isError: true,
@@ -1 +1 @@
1
- {"version":3,"file":"verificar-oc.js","sourceRoot":"","sources":["../../src/tools/verificar-oc.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"verificar-oc.js","sourceRoot":"","sources":["../../src/tools/verificar-oc.ts"],"names":[],"mappings":"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"}