diff --git a/network-poc/frontend/src/pages/index.astro b/network-poc/frontend/src/pages/index.astro
index 50b9cea..f8b35d2 100644
--- a/network-poc/frontend/src/pages/index.astro
+++ b/network-poc/frontend/src/pages/index.astro
@@ -792,22 +792,37 @@ OUTPUT FORMAT:
const allCode = Object.entries(files).map(([n,c]) => `--- ${n} ---\n${c}`).join('\n\n');
let stepN = template.order.length + 1;
- // DevOps/Testaaja: koodikatselmointi
+ // Review-korjausluuppi: max 2 kierrosta
const tst = agents.tester || Object.values(agents)[4];
- termLog(`\n[${stepN}] ${esc(tst.name)} — koodikatselmointi`);
- highlightAgent('tester');
- explainStep('Koodikatselmointi', `${tst.name} tarkistaa importit, nimeämiset, virheenkäsittelyn ja tiedostojen yhteensopivuuden.`);
- const tstPrompt = (tst.prompt ? tst.prompt+'\n\n' : '') + `Review this project:\n\n${allCode}`;
- const review = await kpnRun(tst.model, tstPrompt);
- stepN++;
+ const MAX_REVIEW_ROUNDS = 2;
- // Korjausluuppi (jos tarpeen) — korjatut tiedostot päivitetään files-objektiin
- if (review && !review.toLowerCase().includes('lgtm')) {
- termLog(`\n[${stepN}] ${esc(cdr.name)} — korjaukset`);
+ for (let round = 0; round < MAX_REVIEW_ROUNDS; round++) {
+ const currentCode = Object.entries(files).map(([n,c]) => `--- ${n} ---\n${c}`).join('\n\n');
+
+ // DevOps review
+ termLog(`\n[${stepN}] ${esc(tst.name)} — koodikatselmointi${round > 0 ? ' (kierros '+(round+1)+')' : ''}`);
+ highlightAgent('tester');
+ if (round === 0) explainStep('Koodikatselmointi', `${tst.name} analysoi koodin rivi riviltä: importit, nimeämiset, virheenkäsittely, tietoturva.`);
+ else explainStep('Uudelleentarkistus', `${tst.name} tarkistaa korjaukset.`);
+
+ const reviewPrompt = (tst.prompt ? tst.prompt+'\n\n' : '') + `Review this project:\n\n${currentCode}`;
+ const review = await kpnRun(tst.model, reviewPrompt);
+ stepN++;
+
+ // LGTM → ei korjauksia tarvita
+ if (!review || review.toLowerCase().includes('lgtm')) {
+ termLog(` ✓ ${esc(tst.name)}: LGTM`);
+ break;
+ }
+
+ // Korjaukset
+ termLog(`\n[${stepN}] ${esc(cdr.name)} — korjaukset${round > 0 ? ' (kierros '+(round+1)+')' : ''}`);
highlightAgent('coder');
- explainStep('Korjausluuppi', `${tst.name} löysi ongelmia. ${cdr.name} korjaa ja palauttaa päivitetyt tiedostot.`);
- const fixPrompt = `${cdr.prompt ? cdr.prompt+'\n\n' : ''}Fix these issues:\n${review}\n\nCurrent code:\n${allCode}\n\nWrite ALL corrected files. Start each file with: --- filename.py ---`;
+ explainStep('Korjaus', `${tst.name} löysi ongelmia. ${cdr.name} saa palautteen ja korjaa.`);
+
+ const fixPrompt = `${cdr.prompt ? cdr.prompt+'\n\n' : ''}Fix these issues:\n${review}\n\nCurrent code:\n${currentCode}\n\nWrite ALL corrected files. Start each file with: --- filename.py ---`;
const fixedCode = await kpnRun(cdr.model, fixPrompt);
+
// Parsitaan korjatut tiedostot takaisin files-objektiin
if (fixedCode) {
const fixedParts = fixedCode.split(/^---\s*(\S+)\s*---$/m);
@@ -820,7 +835,7 @@ OUTPUT FORMAT:
}
}
stepN++;
- }
+ } // for review round
// Päivitetään allCode korjausten jälkeen
const updatedCode = Object.entries(files).map(([n,c]) => `--- ${n} ---\n${c}`).join('\n\n');