Avatarit vaihtuvat pystyyn pipelinen aikana, aktiivinen agentti highlightataan
Pipeline käynnistyessä: - Avataririvi vaihtuu pystyyn (column) → näkee kuka tekee mitä - Aktiivinen agentti saa glow-highlightin (coder sininen, tester sininen) - Korjausvaiheessa koodari highlightataan uudelleen Pipeline valmistuttua: - Palautetaan vaakarivi (row) - Poistetaan highlight Poistettu manuaalinen layout-toggle-nappi — layout on automaattinen. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,13 +4,10 @@
|
|||||||
<div id="agent-bar" style="display:flex;gap:6px;align-items:flex-end;flex-wrap:wrap">
|
<div id="agent-bar" style="display:flex;gap:6px;align-items:flex-end;flex-wrap:wrap">
|
||||||
<!-- Renderöidään JS:stä -->
|
<!-- Renderöidään JS:stä -->
|
||||||
</div>
|
</div>
|
||||||
<!-- + Lisää agentti + layout-toggle -->
|
<!-- + Lisää agentti -->
|
||||||
<div style="display:flex;flex-direction:column;gap:4px;align-items:center">
|
<div id="add-agent-btn" class="agent-avatar" onclick="addCustomAgent()" title="Lisää oma agentti" style="opacity:0.4">
|
||||||
<div id="add-agent-btn" class="agent-avatar" onclick="addCustomAgent()" title="Lisää oma agentti" style="opacity:0.4">
|
<div style="width:48px;height:48px;border-radius:50%;border:2px dashed var(--border);display:flex;align-items:center;justify-content:center;font-size:24px;color:var(--border)">+</div>
|
||||||
<div style="width:48px;height:48px;border-radius:50%;border:2px dashed var(--border);display:flex;align-items:center;justify-content:center;font-size:24px;color:var(--border)">+</div>
|
<span style="font-size:10px;color:#8b949e;text-align:center;display:block">Lisää</span>
|
||||||
<span style="font-size:10px;color:#8b949e;text-align:center;display:block">Lisää</span>
|
|
||||||
</div>
|
|
||||||
<button id="layout-toggle" onclick="toggleAgentLayout()" class="btn btn-muted" style="font-size:10px;padding:2px 6px" title="Vaihda vaaka/pysty">☰</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -216,15 +216,19 @@ OUTPUT FORMAT:
|
|||||||
// === Agent selection & config ===
|
// === Agent selection & config ===
|
||||||
let selectedAgent = null;
|
let selectedAgent = null;
|
||||||
|
|
||||||
// Layout: vaaka/pysty toggle
|
// Layout: vaaka (oletus) → pysty kun pipeline pyörii
|
||||||
let agentLayout = localStorage.getItem('kpn-agent-layout') || 'row';
|
function setAgentLayout(layout) {
|
||||||
window.toggleAgentLayout = function() {
|
|
||||||
agentLayout = agentLayout === 'row' ? 'column' : 'row';
|
|
||||||
localStorage.setItem('kpn-agent-layout', agentLayout);
|
|
||||||
const bar = document.getElementById('agent-bar');
|
const bar = document.getElementById('agent-bar');
|
||||||
bar.style.flexDirection = agentLayout;
|
if (!bar) return;
|
||||||
bar.style.alignItems = agentLayout === 'column' ? 'flex-start' : 'flex-end';
|
bar.style.flexDirection = layout;
|
||||||
};
|
bar.style.alignItems = layout === 'column' ? 'flex-start' : 'flex-end';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Highlightaa aktiivinen agentti pipeline-aikana
|
||||||
|
function highlightAgent(agentKey) {
|
||||||
|
document.querySelectorAll('.agent-avatar').forEach(el => el.classList.remove('active'));
|
||||||
|
if (agentKey) document.querySelector(`.agent-avatar[data-agent="${agentKey}"]`)?.classList.add('active');
|
||||||
|
}
|
||||||
|
|
||||||
function renderAgentBar() {
|
function renderAgentBar() {
|
||||||
const bar = document.getElementById('agent-bar');
|
const bar = document.getElementById('agent-bar');
|
||||||
@@ -721,10 +725,14 @@ OUTPUT FORMAT:
|
|||||||
const cdr = agents.coder || Object.values(agents)[1];
|
const cdr = agents.coder || Object.values(agents)[1];
|
||||||
const tst = agents.tester || Object.values(agents)[2];
|
const tst = agents.tester || Object.values(agents)[2];
|
||||||
|
|
||||||
|
// Vaihdetaan pystyyn pipelinen ajaksi
|
||||||
|
setAgentLayout('column');
|
||||||
|
|
||||||
// Etsitään sopivin mallipohja
|
// Etsitään sopivin mallipohja
|
||||||
const template = Object.values(templates)[0]; // Toistaiseksi vain FastAPI CRUD
|
const template = Object.values(templates)[0]; // Toistaiseksi vain FastAPI CRUD
|
||||||
if (!template) {
|
if (!template) {
|
||||||
termLog(' ✗ Mallipohjia ei ladattu', '#f85149');
|
termLog(' ✗ Mallipohjia ei ladattu', '#f85149');
|
||||||
|
setAgentLayout('row');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -740,6 +748,7 @@ OUTPUT FORMAT:
|
|||||||
|
|
||||||
const step = i + 1;
|
const step = i + 1;
|
||||||
termLog(`\n<span style="color:#3fb950;font-weight:bold">[${step}/${template.order.length}] ${esc(cdr.name)}</span> — ${esc(fileName)}`);
|
termLog(`\n<span style="color:#3fb950;font-weight:bold">[${step}/${template.order.length}] ${esc(cdr.name)}</span> — ${esc(fileName)}`);
|
||||||
|
highlightAgent('coder');
|
||||||
|
|
||||||
// Opettava selitys: miksi tämä tiedosto, mitä se sisältää
|
// Opettava selitys: miksi tämä tiedosto, mitä se sisältää
|
||||||
explainStep(fileName, fileDef.instructions);
|
explainStep(fileName, fileDef.instructions);
|
||||||
@@ -779,6 +788,7 @@ OUTPUT FORMAT:
|
|||||||
// Review
|
// Review
|
||||||
const allCode = Object.entries(files).map(([n,c]) => `--- ${n} ---\n${c}`).join('\n\n');
|
const allCode = Object.entries(files).map(([n,c]) => `--- ${n} ---\n${c}`).join('\n\n');
|
||||||
termLog(`\n<span style="color:var(--accent);font-weight:bold">[${template.order.length + 1}] ${esc(tst.name)}</span> — review`);
|
termLog(`\n<span style="color:var(--accent);font-weight:bold">[${template.order.length + 1}] ${esc(tst.name)}</span> — review`);
|
||||||
|
highlightAgent('tester');
|
||||||
explainStep('Koodikatselmointi', 'Testaaja tarkistaa importit, nimeämiset, puuttuvat virheenkäsittelyt ja tiedostojen yhteensopivuuden.');
|
explainStep('Koodikatselmointi', 'Testaaja tarkistaa importit, nimeämiset, puuttuvat virheenkäsittelyt ja tiedostojen yhteensopivuuden.');
|
||||||
|
|
||||||
const tstPrompt = (tst.prompt ? tst.prompt+'\n\n' : '') +
|
const tstPrompt = (tst.prompt ? tst.prompt+'\n\n' : '') +
|
||||||
@@ -787,10 +797,15 @@ OUTPUT FORMAT:
|
|||||||
|
|
||||||
if (review && !review.toLowerCase().includes('lgtm')) {
|
if (review && !review.toLowerCase().includes('lgtm')) {
|
||||||
termLog(`\n<span style="color:#d29922;font-weight:bold">[${template.order.length + 2}] ${esc(cdr.name)}</span> — korjaukset`);
|
termLog(`\n<span style="color:#d29922;font-weight:bold">[${template.order.length + 2}] ${esc(cdr.name)}</span> — korjaukset`);
|
||||||
|
highlightAgent('coder');
|
||||||
explainStep('Korjausluuppi', 'Testaaja löysi ongelmia. Koodari saa palautteen ja korjaa koodin.');
|
explainStep('Korjausluuppi', 'Testaaja löysi ongelmia. Koodari 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.`);
|
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.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pipeline valmis — palautetaan vaaka ja poistetaan highlight
|
||||||
|
setAgentLayout('row');
|
||||||
|
highlightAgent(null);
|
||||||
|
|
||||||
termLog(`\n<span style="color:var(--purple);font-weight:bold">━━━ Valmis (${Object.keys(files).length} tiedostoa) ━━━</span>`);
|
termLog(`\n<span style="color:var(--purple);font-weight:bold">━━━ Valmis (${Object.keys(files).length} tiedostoa) ━━━</span>`);
|
||||||
explainStep('Tulos', `Projekti "${task}" generoitu ${Object.keys(files).length} tiedostoon. Klikkaa "Avaa editorissa" tutkiaksesi koodia. Aja: uv run uvicorn main:app --reload`);
|
explainStep('Tulos', `Projekti "${task}" generoitu ${Object.keys(files).length} tiedostoon. Klikkaa "Avaa editorissa" tutkiaksesi koodia. Aja: uv run uvicorn main:app --reload`);
|
||||||
renderProjectCard(files, task);
|
renderProjectCard(files, task);
|
||||||
|
|||||||
Reference in New Issue
Block a user