From f497da836c23d63c1b2d2045097409e2ca504752 Mon Sep 17 00:00:00 2001 From: Milton Gonzalez Date: Fri, 23 Oct 2026 17:37:30 -0500 Subject: [PATCH] fix: version 4.0.5 -- Propuestas de IA grandes ya no quedan cortadas Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 7 +++++++ VERSION | 2 +- backend/package.json | 2 +- backend/src/modules/ai/service.js | 4 ++-- backend/src/utils/ai.js | 4 +++- frontend/package.json | 2 +- 6 files changed, 15 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05cd39d..bd5d804 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog - project.linkedcorp.net +## [4.0.5] - 2026-10-23 +### Fixed +- "No se pudo generar un plan con tareas": con 4.000 tokens de tope, una propuesta grande (con + el razonamiento del modelo) podía quedar cortada y llegar sin actividades. Tope subido a + 12.000 (solo se cobra lo usado) y, si aun así se corta, se informa con un mensaje claro. El log + registra el motivo de fin de cada llamada. + ## [4.0.4] - 2026-10-23 ### Changed - "Nuevo con IA" también detecta cuando lo pedido ya existe como actividad o tarea dentro de otro diff --git a/VERSION b/VERSION index c5106e6..7636e75 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.0.4 +4.0.5 diff --git a/backend/package.json b/backend/package.json index bd681c0..9559f0b 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "project-linkedcorp-backend", - "version": "4.0.4", + "version": "4.0.5", "private": true, "type": "module", "main": "src/server.js", diff --git a/backend/src/modules/ai/service.js b/backend/src/modules/ai/service.js index 6e4034e..4e7428d 100644 --- a/backend/src/modules/ai/service.js +++ b/backend/src/modules/ai/service.js @@ -120,7 +120,7 @@ export async function generateProjectPlan(projectId, description, lang, user) { ].filter(Boolean).join('\n'), toolName: 'plan_de_proyecto', schema: { type: 'object', properties: { activities: ACTIVITIES_SCHEMA }, required: ['activities'] }, - maxTokens: 4000, + maxTokens: 12000, }); await logAudit({ userId: user.id, action: 'ai_plan', entityType: 'project', entityId: projectId }); return { activities: cleanPlan(result.activities) }; @@ -192,7 +192,7 @@ export async function proposeNewProject({ objective, startDate, lang }, user) { }, required: ['isProject'], }, - maxTokens: 4000, + maxTokens: 12000, }); await logAudit({ userId: user.id, action: 'ai_new_project', entityType: 'project', entityId: null }); if (!result.isProject) throw new HttpError(422, 'Solo puedo ayudarte a crear proyectos. Describe el objetivo de un proyecto de trabajo.'); diff --git a/backend/src/utils/ai.js b/backend/src/utils/ai.js index 5ff44c3..1d4c475 100644 --- a/backend/src/utils/ai.js +++ b/backend/src/utils/ai.js @@ -40,7 +40,9 @@ export async function askStructured({ system, prompt, toolName, schema, maxToken throw new HttpError(502, `Servicio de IA: ${detail}`); } // Consumo real de cada llamada (para estimar costos: ver precios del modelo en la consola). - console.log(`[ai] ${config.model} tokens entrada=${body?.usage?.input_tokens} salida=${body?.usage?.output_tokens}`); + console.log(`[ai] ${config.model} tokens entrada=${body?.usage?.input_tokens} salida=${body?.usage?.output_tokens} fin=${body?.stop_reason}`); + // Respuesta cortada por el tope de tokens: el JSON de la herramienta llega incompleto. + if (body?.stop_reason === 'max_tokens') throw new HttpError(502, 'La respuesta de la IA fue demasiado larga y quedo incompleta. Intenta con un objetivo mas acotado.'); const tool = body?.content?.find((c) => c.type === 'tool_use'); if (!tool?.input) throw new HttpError(502, 'La IA no devolvio un resultado valido'); return tool.input; diff --git a/frontend/package.json b/frontend/package.json index 6592190..d3ce0b0 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "project-linkedcorp-frontend", "private": true, - "version": "4.0.4", + "version": "4.0.5", "type": "module", "scripts": { "dev": "vite",