diff --git a/network-poc/frontend/src/pages/index.astro b/network-poc/frontend/src/pages/index.astro
index 37c523d..c5f1ace 100644
--- a/network-poc/frontend/src/pages/index.astro
+++ b/network-poc/frontend/src/pages/index.astro
@@ -735,8 +735,14 @@ OUTPUT FORMAT:
if (!fileDef) continue;
const step = i + 1;
- termLog(`\n[${step}/${template.order.length}] ${esc(cdr.name)} — ${esc(fileName)}`);
- highlightAgent('coder');
+ // Valitaan oikea agentti tiedostotyypin mukaan
+ const isDbFile = fileName === 'models.py' || fileName === 'database.py';
+ const dataAgent = agents.data || Object.values(agents)[2];
+ const fileAgent = isDbFile && dataAgent ? dataAgent : cdr;
+ const fileAgentKey = isDbFile && dataAgent ? 'data' : 'coder';
+
+ termLog(`\n[${step}/${template.order.length}] ${esc(fileAgent.name)} — ${esc(fileName)}`);
+ highlightAgent(fileAgentKey);
// Opettava selitys: miksi tämä tiedosto, mitä se sisältää
explainStep(fileName, fileDef.instructions);
@@ -744,8 +750,8 @@ OUTPUT FORMAT:
// Rakennetaan prompti: esimerkki + konteksti + ohje
let prompt = '';
- // Agentin system prompt
- if (cdr.prompt) prompt += cdr.prompt + '\n\n';
+ // Agentin system prompt (data-agentti models.py:lle, koodari muille)
+ if (fileAgent.prompt) prompt += fileAgent.prompt + '\n\n';
// Esimerkki (few-shot)
prompt += `EXAMPLE of ${fileName} (for a different project, adapt to this one):\n`;
@@ -765,7 +771,7 @@ OUTPUT FORMAT:
prompt += fileDef.instructions + '\n';
prompt += 'Adapt the example to match the project description. Import from already written files. Write ONLY the code, no explanations.';
- const code = await kpnRun(cdr.model, prompt);
+ const code = await kpnRun(fileAgent.model, prompt);
if (!code) {
termLog(` ✗ Keskeytyi (${fileName})`, '#f85149');
return;
@@ -773,24 +779,52 @@ OUTPUT FORMAT:
files[fileName] = code;
}
- // Review
const allCode = Object.entries(files).map(([n,c]) => `--- ${n} ---\n${c}`).join('\n\n');
- termLog(`\n[${template.order.length + 1}] ${esc(tst.name)} — review`);
+ let stepN = template.order.length + 1;
+
+ // DevOps/Testaaja: koodikatselmointi
+ const tst = agents.tester || Object.values(agents)[4];
+ termLog(`\n[${stepN}] ${esc(tst.name)} — koodikatselmointi`);
highlightAgent('tester');
- explainStep('Koodikatselmointi', 'Testaaja tarkistaa importit, nimeämiset, puuttuvat virheenkäsittelyt ja tiedostojen yhteensopivuuden.');
-
- const tstPrompt = (tst.prompt ? tst.prompt+'\n\n' : '') +
- `Review this project. Check:\n1. All imports are correct (files import from each other)\n2. Pydantic schema names don't conflict with SQLAlchemy models\n3. All CRUD endpoints exist\n4. Error handling is present\nIf everything is correct, say "LGTM". Otherwise list specific issues.\n\n${allCode}`;
+ 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++;
+ // Korjausluuppi (jos tarpeen)
if (review && !review.toLowerCase().includes('lgtm')) {
- termLog(`\n[${template.order.length + 2}] ${esc(cdr.name)} — korjaukset`);
+ termLog(`\n[${stepN}] ${esc(cdr.name)} — korjaukset`);
highlightAgent('coder');
- explainStep('Korjausluuppi', 'Testaaja löysi ongelmia. Koodari saa palautteen ja korjaa koodin.');
+ explainStep('Korjausluuppi', `${tst.name} löysi ongelmia. ${cdr.name} saa palautteen ja korjaa koodin.`);
await kpnRun(cdr.model, `${cdr.prompt ? cdr.prompt+'\n\n' : ''}Fix these issues:\n${review}\n\nCurrent code:\n${allCode}\n\nWrite the corrected files.`);
+ stepN++;
}
- // Pipeline valmis — poistetaan highlight
+ // QA: testit
+ const qaAgent = agents.qa || Object.values(agents)[3];
+ if (qaAgent) {
+ termLog(`\n[${stepN}] ${esc(qaAgent.name)} — testit`);
+ highlightAgent('qa');
+ explainStep('Testit', `${qaAgent.name} kirjoittaa pytest-testit kaikille endpointeille.`);
+ const qaPrompt = (qaAgent.prompt ? qaAgent.prompt+'\n\n' : '') + `Write pytest tests for this project:\n\n${allCode}\n\nWrite a complete test_main.py file with TestClient.`;
+ const tests = await kpnRun(qaAgent.model, qaPrompt);
+ if (tests) files['test_main.py'] = tests;
+ stepN++;
+ }
+
+ // Tarkkailija: riskianalyysi
+ const obs = agents.observer || Object.values(agents)[5];
+ if (obs) {
+ termLog(`\n[${stepN}] ${esc(obs.name)} — riskianalyysi`);
+ highlightAgent('observer');
+ explainStep('Riskianalyysi', `${obs.name} arvioi arkkitehtuurin, tietoturvan ja ylläpidettävyyden.`);
+ const finalCode = Object.entries(files).map(([n,c]) => `--- ${n} ---\n${c}`).join('\n\n');
+ const obsPrompt = (obs.prompt ? obs.prompt+'\n\n' : '') + `Evaluate this project:\n\n${finalCode}`;
+ await kpnRun(obs.model, obsPrompt);
+ stepN++;
+ }
+
+ // Pipeline valmis
highlightAgent(null);
termLog(`\n━━━ Valmis (${Object.keys(files).length} tiedostoa) ━━━`);