agent-mp 0.5.27 → 0.5.29
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.
- package/dist/core/engine.js +95 -10
- package/package.json +1 -1
package/dist/core/engine.js
CHANGED
|
@@ -415,11 +415,15 @@ MODO SPEC — Feature cargada: "${activeFeatureId}"
|
|
|
415
415
|
Los archivos raw YA ESTÁN en el CONTEXTO DEL PROYECTO arriba.
|
|
416
416
|
|
|
417
417
|
REGLAS CRÍTICAS:
|
|
418
|
-
1. ANTES DE ESCRIBIR CUALQUIER COSA: leé completo
|
|
419
|
-
2.
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
418
|
+
1. ANTES DE ESCRIBIR CUALQUIER COSA: leé completo el CONTEXTO DEL PROYECTO, incluyendo la sección "TAREA EXISTENTE" si está presente.
|
|
419
|
+
2. SI EXISTE "TAREA EXISTENTE" en el contexto:
|
|
420
|
+
- Si hay SPEC.MD EXISTENTE: NO lo regeneres. Usalo como referencia.
|
|
421
|
+
- Si hay RESULTADO PREVIO: FAIL: informá al usuario qué falló y preguntá si quiere corregir eso específico.
|
|
422
|
+
- Si ya hay plan.json: NO generes otro spec — la tarea ya está definida.
|
|
423
|
+
3. NO preguntes sobre información que ya está en los archivos raw o en TAREA EXISTENTE.
|
|
424
|
+
4. Solo hacé preguntas sobre información que GENUINAMENTE falta y que no podés inferir del contexto.
|
|
425
|
+
5. Si los archivos ya tienen suficiente información para entender el objetivo, NO hagas preguntas — usá el spec existente.
|
|
426
|
+
6. Cuando tengas todo claro (o si ya hay spec), generá el spec.md SOLO si NO existe uno previo:
|
|
423
427
|
|
|
424
428
|
=== SPEC.MD ===
|
|
425
429
|
# Feature: ${activeFeatureId}
|
|
@@ -440,7 +444,7 @@ REGLAS CRÍTICAS:
|
|
|
440
444
|
[consideraciones de implementación]
|
|
441
445
|
=== END SPEC.MD ===
|
|
442
446
|
|
|
443
|
-
|
|
447
|
+
7. Cuando el spec esté aprobado (o si ya existe), escribí EXACTAMENTE al final: ${READY_SENTINEL}` : `
|
|
444
448
|
MODO TAREA LIBRE — No se especificó feature todavía.
|
|
445
449
|
${featureListBlock}
|
|
446
450
|
REGLAS:
|
|
@@ -463,8 +467,10 @@ ${conversationHistory}
|
|
|
463
467
|
|
|
464
468
|
INSTRUCCIONES GENERALES:
|
|
465
469
|
- Hablá en forma NATURAL, como un compañero de equipo experimentado.
|
|
466
|
-
- ANTES DE RESPONDER: leé todo el CONTEXTO DEL PROYECTO
|
|
467
|
-
-
|
|
470
|
+
- ANTES DE RESPONDER: leé todo el CONTEXTO DEL PROYECTO, incluyendo "TAREA EXISTENTE" si está presente.
|
|
471
|
+
- Si hay una TAREA EXISTENTE con RESULTADO PREVIO: FAIL, informá al usuario qué falló y preguntá si quiere corregir eso específico.
|
|
472
|
+
- Si ya hay SPEC.MD o plan.json para la tarea, NO los regeneres — usá los existentes.
|
|
473
|
+
- NO preguntés cosas que ya están respondidas en los archivos raw, TAREA EXISTENTE o la conversación.
|
|
468
474
|
- Hacé como máximo UNA pregunta por turno.
|
|
469
475
|
- NO uses JSON, hablá normalmente.
|
|
470
476
|
- Sé directo y eficiente — respetá el tiempo del programador.${specInstructions}`;
|
|
@@ -981,6 +987,41 @@ REGLA: Al terminar, reporta todo lo que encontraste de forma clara y estructurad
|
|
|
981
987
|
ctx += `--- END FEATURE ---\n`;
|
|
982
988
|
}
|
|
983
989
|
}
|
|
990
|
+
// VERIFICAR SI EXISTE TAREA PARA ESTA FEATURE — incluir estado y resultado previo
|
|
991
|
+
const taskDir = path.join(this.projectDir, '.agent', 'tasks', featureId);
|
|
992
|
+
if (await fileExists(taskDir)) {
|
|
993
|
+
ctx += `\n\n--- TAREA EXISTENTE: ${featureId} ---\n`;
|
|
994
|
+
// Leer plan.json si existe
|
|
995
|
+
const planPath = path.join(taskDir, 'plan.json');
|
|
996
|
+
if (await fileExists(planPath)) {
|
|
997
|
+
const plan = await readJson(planPath);
|
|
998
|
+
ctx += `\nPLAN EXISTENTE:\n- Descripción: ${plan.description || 'N/A'}\n- Steps: ${plan.steps?.length || 0}\n`;
|
|
999
|
+
}
|
|
1000
|
+
// Leer progress.json si existe
|
|
1001
|
+
const progressPath = path.join(taskDir, 'progress.json');
|
|
1002
|
+
if (await fileExists(progressPath)) {
|
|
1003
|
+
const progress = await readJson(progressPath);
|
|
1004
|
+
ctx += `- Estado: ${progress.status || 'unknown'}\n`;
|
|
1005
|
+
}
|
|
1006
|
+
// Leer result.md si existe — ESTO ES CRÍTICO PARA RE-INTENTOS
|
|
1007
|
+
const resultPath = path.join(taskDir, 'result.md');
|
|
1008
|
+
if (await fileExists(resultPath)) {
|
|
1009
|
+
const result = await readFile(resultPath);
|
|
1010
|
+
const verdict = result.includes('PASS') || result.includes('✅') ? 'PASS' : 'FAIL';
|
|
1011
|
+
ctx += `- RESULTADO PREVIO: ${verdict}\n`;
|
|
1012
|
+
if (verdict === 'FAIL') {
|
|
1013
|
+
ctx += `\n⚠️ ESTA TAREA YA FALLÓ ANTES. Razones del FAIL:\n${result.slice(0, 1500)}\n`;
|
|
1014
|
+
ctx += `\nIMPORTANTE: Si el usuario pide re-implementar, debés corregir ESPECÍFICAMENTE los puntos marcados como FAIL.\n`;
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
// Leer spec.md si existe
|
|
1018
|
+
const specPath = path.join(this.projectDir, '.agent', 'docs', featureId, 'spec.md');
|
|
1019
|
+
if (await fileExists(specPath)) {
|
|
1020
|
+
const spec = await readFile(specPath);
|
|
1021
|
+
ctx += `\n--- SPEC.MD EXISTENTE (usar como referencia, NO regenerar) ---\n${spec.slice(0, 2000)}\n`;
|
|
1022
|
+
}
|
|
1023
|
+
ctx += `--- END TAREA ---\n`;
|
|
1024
|
+
}
|
|
984
1025
|
}
|
|
985
1026
|
return ctx;
|
|
986
1027
|
}
|
|
@@ -1085,6 +1126,41 @@ INSTRUCCIONES:
|
|
|
1085
1126
|
async runImplementor(taskId, plan) {
|
|
1086
1127
|
const taskDir = path.join(this.projectDir, '.agent', 'tasks', taskId);
|
|
1087
1128
|
log.phase(2, 'Implementacion', this.config.roles.implementor.cli, this.config.roles.implementor.model);
|
|
1129
|
+
// VERIFICAR SI YA EXISTE UN RESULT.MD PREVIO (para detectar re-intentos)
|
|
1130
|
+
const resultPath = path.join(taskDir, 'result.md');
|
|
1131
|
+
if (await fileExists(resultPath)) {
|
|
1132
|
+
const prevResult = await readFile(resultPath);
|
|
1133
|
+
const isFail = prevResult.toUpperCase().includes('FAIL') || prevResult.includes('❌');
|
|
1134
|
+
if (isFail) {
|
|
1135
|
+
log.warn('⚠️ Esta tarea YA fue implementada antes y el REVIEWER marcó FAIL');
|
|
1136
|
+
console.log('');
|
|
1137
|
+
console.log(chalk.yellow(' Resultado previo:'));
|
|
1138
|
+
console.log(chalk.dim(' ' + prevResult.split('\n').slice(0, 15).join('\n ')));
|
|
1139
|
+
if (prevResult.split('\n').length > 15) {
|
|
1140
|
+
console.log(chalk.dim(' ... (ver result.md completo para más detalles)'));
|
|
1141
|
+
}
|
|
1142
|
+
console.log('');
|
|
1143
|
+
// Preguntar al usuario qué hacer
|
|
1144
|
+
const action = await ask(' La tarea falló antes. ¿Qué querés hacer?\n (r=reintentar arreglando el error / v=ver result.md completo / c=cancelar): ', this.rl, this.fi);
|
|
1145
|
+
if (action.toLowerCase() === 'v') {
|
|
1146
|
+
console.log('');
|
|
1147
|
+
console.log(chalk.cyan(' === result.md completo ==='));
|
|
1148
|
+
console.log(chalk.white(prevResult));
|
|
1149
|
+
console.log(chalk.cyan(' =========================='));
|
|
1150
|
+
console.log('');
|
|
1151
|
+
const retry = await ask(' ¿Reintentar igual? (y/n): ', this.rl, this.fi);
|
|
1152
|
+
if (retry.toLowerCase() !== 'y') {
|
|
1153
|
+
log.info('Implementación cancelada por el usuario.');
|
|
1154
|
+
throw new Error('USER_CANCELLED_AFTER_FAIL');
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
else if (action.toLowerCase() === 'c' || action.toLowerCase() === 'n') {
|
|
1158
|
+
log.info('Implementación cancelada por el usuario.');
|
|
1159
|
+
throw new Error('USER_CANCELLED_AFTER_FAIL');
|
|
1160
|
+
}
|
|
1161
|
+
// Si es 'r', continúa con la implementación
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1088
1164
|
const structurePath = path.join(this.projectDir, '.agent', 'rules', 'structure.md');
|
|
1089
1165
|
let structureRules = '';
|
|
1090
1166
|
if (await fileExists(structurePath)) {
|
|
@@ -1099,6 +1175,14 @@ INSTRUCCIONES:
|
|
|
1099
1175
|
}
|
|
1100
1176
|
const allTargetFiles = [...new Set(plan.steps.flatMap((s) => s.files || []))];
|
|
1101
1177
|
const stepsText = plan.steps.map((s) => `Step ${s.num}: ${s.description}${s.files?.length ? `\n Archivos: ${s.files.join(', ')}` : ''}`).join('\n');
|
|
1178
|
+
// Si existe result.md previo con FAIL, incluirlo en el prompt para que el implementor sepa qué corregir
|
|
1179
|
+
let failContext = '';
|
|
1180
|
+
if (await fileExists(resultPath)) {
|
|
1181
|
+
const prevResult = await readFile(resultPath);
|
|
1182
|
+
if (prevResult.toUpperCase().includes('FAIL') || prevResult.includes('❌')) {
|
|
1183
|
+
failContext = `\n\n⚠️ INTENTO PREVIO FALLIDO — El reviewer marcó estos errores:\n=== RESULT.MD PREVIO ===\n${prevResult}\n======================\n\nIMPORTANTE: Debés corregir ESPECÍFICAMENTE los puntos marcados como FAIL en el result.md previo. No vuelvas a implementar lo mismo sin corregir los errores señalados.\n`;
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1102
1186
|
// The engine writes files itself — ask the LLM to generate content in parseable blocks.
|
|
1103
1187
|
// This avoids depending on CLI tool-use capabilities which are unavailable in API mode.
|
|
1104
1188
|
const prompt = `TAREA: ${plan.description}
|
|
@@ -1111,7 +1195,7 @@ ${allTargetFiles.length ? `ARCHIVOS A CREAR/MODIFICAR:\n${allTargetFiles.map(f =
|
|
|
1111
1195
|
|
|
1112
1196
|
${context ? `CONTEXTO DEL PROYECTO:\n${context.slice(0, 2000)}\n` : ''}
|
|
1113
1197
|
${archContext ? `ARQUITECTURA EXISTENTE:\n${archContext}\n` : ''}
|
|
1114
|
-
${structureRules ? `REGLAS DE ESTRUCTURA:\n${structureRules}\n` : ''}
|
|
1198
|
+
${structureRules ? `REGLAS DE ESTRUCTURA:\n${structureRules}\n` : ''}${failContext}
|
|
1115
1199
|
|
|
1116
1200
|
INSTRUCCIONES CRITICAS:
|
|
1117
1201
|
1. Para CADA archivo que debes crear/modificar, usa este formato EXACTO:
|
|
@@ -1124,7 +1208,8 @@ contenido completo del archivo aqui
|
|
|
1124
1208
|
3. Genera TODOS los archivos necesarios — uno por bloque FILE.
|
|
1125
1209
|
4. Incluye el contenido completo de cada archivo (no fragmentos).
|
|
1126
1210
|
5. Si un step modifica un archivo existente, incluye el archivo completo con los cambios.
|
|
1127
|
-
6. NO incluyas explicaciones fuera de los bloques FILE
|
|
1211
|
+
6. NO incluyas explicaciones fuera de los bloques FILE.
|
|
1212
|
+
7. Si hay un INTENTO PREVIO FALLIDO, leé atentamente los errores del reviewer y CORREGÍ ESPECÍFICAMENTE esos puntos.`;
|
|
1128
1213
|
const res = await this.runWithFallback('implementor', prompt, 'Implementacion');
|
|
1129
1214
|
const text = extractCliText(res);
|
|
1130
1215
|
// Parse === FILE: path === ... === END FILE === blocks written by the LLM
|