agent-mp 0.5.26 → 0.5.28
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 +73 -22
- package/package.json +1 -1
package/dist/core/engine.js
CHANGED
|
@@ -411,13 +411,15 @@ export class AgentEngine {
|
|
|
411
411
|
: '\nNo hay features en .agent/docs/ todavía.\n';
|
|
412
412
|
const READY_SENTINEL = '[LISTO_PARA_LANZAR]';
|
|
413
413
|
const specInstructions = hasFeature ? `
|
|
414
|
-
MODO SPEC
|
|
415
|
-
|
|
414
|
+
MODO SPEC — Feature cargada: "${activeFeatureId}"
|
|
415
|
+
Los archivos raw YA ESTÁN en el CONTEXTO DEL PROYECTO arriba.
|
|
416
416
|
|
|
417
|
-
|
|
418
|
-
1.
|
|
419
|
-
2.
|
|
420
|
-
3.
|
|
417
|
+
REGLAS CRÍTICAS:
|
|
418
|
+
1. ANTES DE ESCRIBIR CUALQUIER COSA: leé completo cada archivo raw del contexto.
|
|
419
|
+
2. NO preguntes sobre información que ya está en los archivos raw. Si el lenguaje, stack, objetivo, contexto o requisitos están en los archivos, USÁ ESA INFORMACIÓN directamente.
|
|
420
|
+
3. Solo hacé preguntas sobre información que GENUINAMENTE falta y que no podés inferir de los archivos.
|
|
421
|
+
4. Si los archivos ya tienen suficiente información para entender el objetivo, NO hagas preguntas — generá el spec.md directamente.
|
|
422
|
+
5. Cuando tengas todo claro (o si los archivos ya tienen suficiente info), generá el spec.md con este formato EXACTO:
|
|
421
423
|
|
|
422
424
|
=== SPEC.MD ===
|
|
423
425
|
# Feature: ${activeFeatureId}
|
|
@@ -438,17 +440,20 @@ FLUJO:
|
|
|
438
440
|
[consideraciones de implementación]
|
|
439
441
|
=== END SPEC.MD ===
|
|
440
442
|
|
|
441
|
-
|
|
442
|
-
MODO TAREA LIBRE
|
|
443
|
+
6. Cuando el spec esté aprobado, escribí EXACTAMENTE al final: ${READY_SENTINEL}` : `
|
|
444
|
+
MODO TAREA LIBRE — No se especificó feature todavía.
|
|
443
445
|
${featureListBlock}
|
|
444
446
|
REGLAS:
|
|
445
|
-
- Primero entendé QUÉ quiere hacer el programador.
|
|
446
|
-
- Si hay features disponibles, preguntá si alguna corresponde
|
|
447
|
-
- Si el programador
|
|
448
|
-
-
|
|
449
|
-
-
|
|
450
|
-
|
|
451
|
-
|
|
447
|
+
- Primero entendé QUÉ quiere hacer el programador.
|
|
448
|
+
- Si hay features disponibles, preguntá UNA VEZ si alguna corresponde (mencioná los nombres). No insistas.
|
|
449
|
+
- Si el programador menciona un path o ID de feature, está confirmando esa feature. NO preguntés "¿tiene que ver con X?" — ya lo dijo. Respondé EXACTAMENTE con: CARGAR_FEATURE: <id>
|
|
450
|
+
- Si el programador menciona solo el nombre o fragmento de un ID de feature disponible, igual respondé con: CARGAR_FEATURE: <id>
|
|
451
|
+
- Cuando el objetivo esté claro, escribí EXACTAMENTE al final: ${READY_SENTINEL}
|
|
452
|
+
- NUNCA escribas ${READY_SENTINEL} si solo recibiste un saludo o falta información concreta.`;
|
|
453
|
+
const prompt = `Sos el COORDINADOR de un equipo de desarrollo de software.
|
|
454
|
+
Tu trabajo es entender qué necesita el programador usando la información disponible y haciendo SOLO las preguntas estrictamente necesarias.
|
|
455
|
+
|
|
456
|
+
REGLA DE ORO: ANTES de escribir cualquier respuesta, LEÉ COMPLETO el CONTEXTO DEL PROYECTO que está arriba. Toda la información que necesitás para no hacer preguntas obvias está ahí.
|
|
452
457
|
|
|
453
458
|
CONTEXTO DEL PROYECTO:
|
|
454
459
|
${context}
|
|
@@ -456,11 +461,13 @@ ${context}
|
|
|
456
461
|
CONVERSACION PREVIA:
|
|
457
462
|
${conversationHistory}
|
|
458
463
|
|
|
459
|
-
INSTRUCCIONES:
|
|
460
|
-
-
|
|
461
|
-
-
|
|
462
|
-
- NO
|
|
463
|
-
-
|
|
464
|
+
INSTRUCCIONES GENERALES:
|
|
465
|
+
- Hablá en forma NATURAL, como un compañero de equipo experimentado.
|
|
466
|
+
- ANTES DE RESPONDER: leé todo el CONTEXTO DEL PROYECTO y los archivos raw de la feature. Si algo ya está documentado ahí, NO lo preguntes.
|
|
467
|
+
- NO preguntés cosas que ya están respondidas en los archivos raw o en la conversación.
|
|
468
|
+
- Hacé como máximo UNA pregunta por turno.
|
|
469
|
+
- NO uses JSON, hablá normalmente.
|
|
470
|
+
- Sé directo y eficiente — respetá el tiempo del programador.${specInstructions}`;
|
|
464
471
|
log.info('Coordinador analizando...');
|
|
465
472
|
const envOverride = {};
|
|
466
473
|
let res;
|
|
@@ -1078,6 +1085,41 @@ INSTRUCCIONES:
|
|
|
1078
1085
|
async runImplementor(taskId, plan) {
|
|
1079
1086
|
const taskDir = path.join(this.projectDir, '.agent', 'tasks', taskId);
|
|
1080
1087
|
log.phase(2, 'Implementacion', this.config.roles.implementor.cli, this.config.roles.implementor.model);
|
|
1088
|
+
// VERIFICAR SI YA EXISTE UN RESULT.MD PREVIO (para detectar re-intentos)
|
|
1089
|
+
const resultPath = path.join(taskDir, 'result.md');
|
|
1090
|
+
if (await fileExists(resultPath)) {
|
|
1091
|
+
const prevResult = await readFile(resultPath);
|
|
1092
|
+
const isFail = prevResult.toUpperCase().includes('FAIL') || prevResult.includes('❌');
|
|
1093
|
+
if (isFail) {
|
|
1094
|
+
log.warn('⚠️ Esta tarea YA fue implementada antes y el REVIEWER marcó FAIL');
|
|
1095
|
+
console.log('');
|
|
1096
|
+
console.log(chalk.yellow(' Resultado previo:'));
|
|
1097
|
+
console.log(chalk.dim(' ' + prevResult.split('\n').slice(0, 15).join('\n ')));
|
|
1098
|
+
if (prevResult.split('\n').length > 15) {
|
|
1099
|
+
console.log(chalk.dim(' ... (ver result.md completo para más detalles)'));
|
|
1100
|
+
}
|
|
1101
|
+
console.log('');
|
|
1102
|
+
// Preguntar al usuario qué hacer
|
|
1103
|
+
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);
|
|
1104
|
+
if (action.toLowerCase() === 'v') {
|
|
1105
|
+
console.log('');
|
|
1106
|
+
console.log(chalk.cyan(' === result.md completo ==='));
|
|
1107
|
+
console.log(chalk.white(prevResult));
|
|
1108
|
+
console.log(chalk.cyan(' =========================='));
|
|
1109
|
+
console.log('');
|
|
1110
|
+
const retry = await ask(' ¿Reintentar igual? (y/n): ', this.rl, this.fi);
|
|
1111
|
+
if (retry.toLowerCase() !== 'y') {
|
|
1112
|
+
log.info('Implementación cancelada por el usuario.');
|
|
1113
|
+
throw new Error('USER_CANCELLED_AFTER_FAIL');
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
else if (action.toLowerCase() === 'c' || action.toLowerCase() === 'n') {
|
|
1117
|
+
log.info('Implementación cancelada por el usuario.');
|
|
1118
|
+
throw new Error('USER_CANCELLED_AFTER_FAIL');
|
|
1119
|
+
}
|
|
1120
|
+
// Si es 'r', continúa con la implementación
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1081
1123
|
const structurePath = path.join(this.projectDir, '.agent', 'rules', 'structure.md');
|
|
1082
1124
|
let structureRules = '';
|
|
1083
1125
|
if (await fileExists(structurePath)) {
|
|
@@ -1092,6 +1134,14 @@ INSTRUCCIONES:
|
|
|
1092
1134
|
}
|
|
1093
1135
|
const allTargetFiles = [...new Set(plan.steps.flatMap((s) => s.files || []))];
|
|
1094
1136
|
const stepsText = plan.steps.map((s) => `Step ${s.num}: ${s.description}${s.files?.length ? `\n Archivos: ${s.files.join(', ')}` : ''}`).join('\n');
|
|
1137
|
+
// Si existe result.md previo con FAIL, incluirlo en el prompt para que el implementor sepa qué corregir
|
|
1138
|
+
let failContext = '';
|
|
1139
|
+
if (await fileExists(resultPath)) {
|
|
1140
|
+
const prevResult = await readFile(resultPath);
|
|
1141
|
+
if (prevResult.toUpperCase().includes('FAIL') || prevResult.includes('❌')) {
|
|
1142
|
+
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`;
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1095
1145
|
// The engine writes files itself — ask the LLM to generate content in parseable blocks.
|
|
1096
1146
|
// This avoids depending on CLI tool-use capabilities which are unavailable in API mode.
|
|
1097
1147
|
const prompt = `TAREA: ${plan.description}
|
|
@@ -1104,7 +1154,7 @@ ${allTargetFiles.length ? `ARCHIVOS A CREAR/MODIFICAR:\n${allTargetFiles.map(f =
|
|
|
1104
1154
|
|
|
1105
1155
|
${context ? `CONTEXTO DEL PROYECTO:\n${context.slice(0, 2000)}\n` : ''}
|
|
1106
1156
|
${archContext ? `ARQUITECTURA EXISTENTE:\n${archContext}\n` : ''}
|
|
1107
|
-
${structureRules ? `REGLAS DE ESTRUCTURA:\n${structureRules}\n` : ''}
|
|
1157
|
+
${structureRules ? `REGLAS DE ESTRUCTURA:\n${structureRules}\n` : ''}${failContext}
|
|
1108
1158
|
|
|
1109
1159
|
INSTRUCCIONES CRITICAS:
|
|
1110
1160
|
1. Para CADA archivo que debes crear/modificar, usa este formato EXACTO:
|
|
@@ -1117,7 +1167,8 @@ contenido completo del archivo aqui
|
|
|
1117
1167
|
3. Genera TODOS los archivos necesarios — uno por bloque FILE.
|
|
1118
1168
|
4. Incluye el contenido completo de cada archivo (no fragmentos).
|
|
1119
1169
|
5. Si un step modifica un archivo existente, incluye el archivo completo con los cambios.
|
|
1120
|
-
6. NO incluyas explicaciones fuera de los bloques FILE
|
|
1170
|
+
6. NO incluyas explicaciones fuera de los bloques FILE.
|
|
1171
|
+
7. Si hay un INTENTO PREVIO FALLIDO, leé atentamente los errores del reviewer y CORREGÍ ESPECÍFICAMENTE esos puntos.`;
|
|
1121
1172
|
const res = await this.runWithFallback('implementor', prompt, 'Implementacion');
|
|
1122
1173
|
const text = extractCliText(res);
|
|
1123
1174
|
// Parse === FILE: path === ... === END FILE === blocks written by the LLM
|