Hardening: lock de sesion atomico, monitor off por defecto, fix DeepSeek reasoning-only
- session_lock: token uuid + compare-and-delete (Lua), TTL > timeout de ejecucion; abort solo limpia el lock tras cancelacion confirmada. Evita doble ejecucion concurrente sobre la misma sesion. - monitor HTTP (puerto 4545) deshabilitado salvo MCP_MONITOR_ENABLED=true y atado a 127.0.0.1; no se acumula historial en memoria si esta off. - DeepSeek/LiteLLM: turnos que llegan solo con reasoning_content (sin content ni tool_calls) ya no rompen la sesion (400 'Invalid assistant message') ni se pintan como 'pensando': se promueven a texto en el historial y en el snapshot persistido. - litellm pinneado a ==1.80.0 (builds reproducibles). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,13 @@ export const CONFIG_FILE_PATH =
|
||||
|
||||
export const MCP_PORT = Number(process.env.MCP_PORT || 3000);
|
||||
export const MONITOR_PORT = Number(process.env.MCP_MONITOR_PORT || 4545);
|
||||
// El monitor HTTP (UI + POST /retry) queda DESACTIVADO por defecto. Solo se
|
||||
// arranca si MCP_MONITOR_ENABLED === 'true' de forma explicita.
|
||||
export const MONITOR_ENABLED =
|
||||
String(process.env.MCP_MONITOR_ENABLED || "").toLowerCase() === "true";
|
||||
// Por seguridad escucha solo en loopback salvo que se defina MCP_MONITOR_HOST.
|
||||
export const MONITOR_HOST = process.env.MCP_MONITOR_HOST || "127.0.0.1";
|
||||
// Compatibilidad: si alguien fuerza MCP_MONITOR_DISABLED tambien lo respetamos.
|
||||
export const MONITOR_DISABLED =
|
||||
String(process.env.MCP_MONITOR_DISABLED || "").toLowerCase() === "1" ||
|
||||
String(process.env.MCP_MONITOR_DISABLED || "").toLowerCase() === "true";
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
// Load configuration first
|
||||
import { loadLocalConfigProfile, applyProfileToEnv } from "./config/index.js";
|
||||
import { loadLocalConfigProfile, applyProfileToEnv, MONITOR_ENABLED, MONITOR_DISABLED } from "./config/index.js";
|
||||
|
||||
// Load and apply config profile (backward compatibility)
|
||||
const selectedProfile = loadLocalConfigProfile();
|
||||
@@ -30,8 +30,11 @@ import { registerResources } from "./resources/index.js";
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
setRegistrationFunctions({ registerPrompts, registerTools, registerResources });
|
||||
|
||||
// Create the shared request monitor (will be applied to each session server)
|
||||
const requestMonitor = createRequestMonitor();
|
||||
// Create the shared request monitor (will be applied to each session server).
|
||||
// Solo se crea si el monitor esta habilitado: asi no acumulamos historial en
|
||||
// memoria ni envolvemos los handlers cuando la UI esta apagada (por defecto).
|
||||
const monitorActive = MONITOR_ENABLED && !MONITOR_DISABLED;
|
||||
const requestMonitor = monitorActive ? createRequestMonitor() : null;
|
||||
|
||||
// Create a server instance for retry functionality in the monitor UI
|
||||
const server = createMcpServer();
|
||||
|
||||
@@ -2,7 +2,7 @@ import http from "node:http";
|
||||
import fsPromises from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { MONITOR_PORT, MONITOR_DISABLED } from "./config/index.js";
|
||||
import { MONITOR_PORT, MONITOR_HOST, MONITOR_ENABLED, MONITOR_DISABLED } from "./config/index.js";
|
||||
import { sessionCredentials } from "./auth/credentials.js";
|
||||
import { activeSessions } from "./httpServer.js";
|
||||
|
||||
@@ -84,8 +84,8 @@ export function broadcastSessionsUpdate() {
|
||||
* Start the monitor HTTP server
|
||||
*/
|
||||
export function startMonitorServer(requestMonitor, toolHandlers) {
|
||||
if (MONITOR_DISABLED) {
|
||||
console.error("MCP monitor UI deshabilitada (MCP_MONITOR_DISABLED=1).");
|
||||
if (!MONITOR_ENABLED || MONITOR_DISABLED) {
|
||||
console.error("[monitor] deshabilitado (MCP_MONITOR_ENABLED!=true)");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -202,12 +202,12 @@ export function startMonitorServer(requestMonitor, toolHandlers) {
|
||||
|
||||
monitorServer.on("error", (error) => {
|
||||
console.warn(
|
||||
`[monitor] No se pudo iniciar la UI en el puerto ${MONITOR_PORT}: ${error.message}. Establece MCP_MONITOR_DISABLED=1 para ocultar este aviso.`
|
||||
`[monitor] No se pudo iniciar la UI en ${MONITOR_HOST}:${MONITOR_PORT}: ${error.message}. Desactiva MCP_MONITOR_ENABLED para ocultar este aviso.`
|
||||
);
|
||||
});
|
||||
|
||||
monitorServer.listen(MONITOR_PORT, '0.0.0.0', () => {
|
||||
console.error(`MCP monitor UI: http://0.0.0.0:${MONITOR_PORT}/monitor`);
|
||||
monitorServer.listen(MONITOR_PORT, MONITOR_HOST, () => {
|
||||
console.error(`MCP monitor UI: http://${MONITOR_HOST}:${MONITOR_PORT}/monitor`);
|
||||
});
|
||||
|
||||
// Broadcast sessions + stats update every 2 seconds for real-time monitoring
|
||||
|
||||
Reference in New Issue
Block a user