From 037bc81936c56fdf6bdd7f2f6587ec34a4a47d99 Mon Sep 17 00:00:00 2001 From: Jordan Date: Mon, 22 Jun 2026 13:20:51 +0100 Subject: [PATCH] Reportar modelo real en no-streaming + prewarm de mcp-server-fetch - engine.py: process_message ahora incluye model/modelUsage en el dict de retorno (no solo en el evento SSE), para que el camino no-streaming (cronjobs -> _report_usage) reporte el modelo real a consumo_acaicode en vez de "unknown". - Dockerfile: precalentar `uvx mcp-server-fetch` en build (como appuser) para que la cache de uv quede en la imagen y el MCP fetch no se quede sin arrancar por timeout en frio tras un rebuild. - mcp.json: startup_timeout de fetch 15 -> 30s como margen. Co-Authored-By: Claude Opus 4.8 (1M context) --- Dockerfile | 7 +++++++ mcp.json | 2 +- src/orchestrator/engine.py | 15 +++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 9b77264..47b9c7b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -56,6 +56,13 @@ USER appuser # Descargar Chromium como appuser (queda en ~/.cache/ms-playwright/) RUN cd mcp-server && npx playwright install chromium +# Precalentar mcp-server-fetch como appuser: uvx descarga ~43 paquetes la +# primera vez, lo que en frio supera el startup_timeout del MCP. Lo dejamos +# cacheado en ~/.cache/uv dentro de la imagen para que arranque rapido en +# runtime (igual que Chromium). El server lee stdin; con /dev/null 2>&1 || true + EXPOSE 8000 CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/mcp.json b/mcp.json index 81bc7b8..3b0f7c1 100644 --- a/mcp.json +++ b/mcp.json @@ -19,7 +19,7 @@ "command": "uvx", "args": ["mcp-server-fetch"], "timeout": 30, - "startup_timeout": 15 + "startup_timeout": 30 } } } diff --git a/src/orchestrator/engine.py b/src/orchestrator/engine.py index ac6be03..b7db70e 100644 --- a/src/orchestrator/engine.py +++ b/src/orchestrator/engine.py @@ -267,6 +267,21 @@ class OrchestratorEngine: "status": "completed", "usage": usage, "total_cost_usd": round(cost_usd, 6), + # Modelo + tarifas realmente usadas. Se incluyen tambien aqui (ademas + # del evento SSE EXECUTION_COMPLETED) para que el camino NO streaming + # (cronjobs -> _report_usage) reporte el modelo correcto a + # consumo_acaicode en vez de "unknown". + "model": model_used, + "modelUsage": { + model_used: { + "inputTokens": total_input, + "outputTokens": total_output, + "costUSD": round(cost_usd, 6), + "inputCost1M": cost_info["input_cost_1m"], + "outputCost1M": cost_info["output_cost_1m"], + "reasoningEffort": self.agent_profile.reasoning_effort or "", + } + }, } def _error_result(self, session: SessionState, error: str) -> dict[str, Any]: