Puhuvat päät agenteille: ? merkki jos agentti kysyy jotain. Lisäksi simulaatio näistä + chattiloki
This commit is contained in:
Binary file not shown.
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Kipinä Agent Dashboard</title>
|
<title>Kipinä Agent Playground</title>
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
--bg-color: #0d1117;
|
--bg-color: #0d1117;
|
||||||
@@ -510,7 +510,6 @@
|
|||||||
filter: grayscale(0%);
|
filter: grayscale(0%);
|
||||||
border-color: var(--accent-color);
|
border-color: var(--accent-color);
|
||||||
box-shadow: 0 0 15px rgba(88, 166, 255, 0.5);
|
box-shadow: 0 0 15px rgba(88, 166, 255, 0.5);
|
||||||
animation: talking-head-gallery 0.4s infinite ease-in-out;
|
|
||||||
transform-origin: bottom center;
|
transform-origin: bottom center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -598,7 +597,6 @@
|
|||||||
}
|
}
|
||||||
.gallery-head-wrap.active:not(.state-question):not(.state-alert)::after {
|
.gallery-head-wrap.active:not(.state-question):not(.state-alert)::after {
|
||||||
content: '💬';
|
content: '💬';
|
||||||
animation: speech-pulse 0.8s infinite ease-in-out;
|
|
||||||
background: #0d1117;
|
background: #0d1117;
|
||||||
border: 1px solid var(--accent-color);
|
border: 1px solid var(--accent-color);
|
||||||
}
|
}
|
||||||
@@ -688,7 +686,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div style="display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 20px;">
|
<div style="display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 20px;">
|
||||||
<div>
|
<div>
|
||||||
<h1 style="margin-bottom:0;" data-i18n="main_title"><span style="color:#ff6b00">Kipinä</span> <span>Agent Dashboard</span></h1>
|
<h1 style="margin-bottom:0;" data-i18n="main_title"><span style="color:#ff6b00">Kipinä</span> <span>Agent Playground</span></h1>
|
||||||
<p class="sub" style="margin-bottom:0;"><span data-i18n="main_subtitle">Hajautettu WebGPU Laskentaverkko</span> · <span id="hub-version" style="color:#58a6ff">-</span></p>
|
<p class="sub" style="margin-bottom:0;"><span data-i18n="main_subtitle">Hajautettu WebGPU Laskentaverkko</span> · <span id="hub-version" style="color:#58a6ff">-</span></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="lang-selector">
|
<div class="lang-selector">
|
||||||
@@ -1084,6 +1082,9 @@
|
|||||||
<div class="gallery-head-wrap" id="wrap-qa"><img src="/avatars/susi_notext.png" id="gallery-qa" class="gallery-head" alt="QA"></div>
|
<div class="gallery-head-wrap" id="wrap-qa"><img src="/avatars/susi_notext.png" id="gallery-qa" class="gallery-head" alt="QA"></div>
|
||||||
<div class="gallery-head-wrap" id="wrap-tester"><img src="/avatars/laiskiainen_notext.png" id="gallery-tester" class="gallery-head" alt="DevOps"></div>
|
<div class="gallery-head-wrap" id="wrap-tester"><img src="/avatars/laiskiainen_notext.png" id="gallery-tester" class="gallery-head" alt="DevOps"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="text-align: center; margin-top: 16px;">
|
||||||
|
<button class="btn" id="simu-btn" onclick="toggleSimulation()" style="font-size: 11px; padding: 4px 10px; background: #0d1a2d; border-color: #58a6ff;">Käynnistä simulaatio</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1275,10 +1276,10 @@
|
|||||||
const agentTitle = (agentPrompts[agent].name.split(' — ')[0] || "AGENTTI").toUpperCase();
|
const agentTitle = (agentPrompts[agent].name.split(' — ')[0] || "AGENTTI").toUpperCase();
|
||||||
|
|
||||||
// Hälytys / Virhe
|
// Hälytys / Virhe
|
||||||
if (pLow.includes('todo') || pLow.includes('viallinen') || pLow.includes('virhe')) {
|
if (pLow.includes('todo') || pLow.includes('viallinen')) {
|
||||||
wrap.classList.add('state-alert');
|
wrap.classList.add('state-alert');
|
||||||
gel.classList.add('state-alert');
|
gel.classList.add('state-alert');
|
||||||
wrap.setAttribute('data-tooltip', `❗ ${agentTitle}: "Kriittinen virhe ohjeistuksessa!"\n(Koodissa tai promptissa esiintyy teksti TODO, viallinen tai virhe. Korjaa ohje välittömästi.)`);
|
wrap.setAttribute('data-tooltip', `❗ ${agentTitle}: "Kriittinen virhe ohjeistuksessa!"\n(Koodissa tai promptissa esiintyy teksti TODO tai viallinen. Korjaa ohje.)`);
|
||||||
}
|
}
|
||||||
// Kysyttävää / Hämmennys
|
// Kysyttävää / Hämmennys
|
||||||
else if (prompt.trim().length <= 15 || prompt.includes('?')) {
|
else if (prompt.trim().length <= 15 || prompt.includes('?')) {
|
||||||
@@ -1301,19 +1302,15 @@
|
|||||||
}
|
}
|
||||||
// Normaali keskustelu aktiivisena
|
// Normaali keskustelu aktiivisena
|
||||||
else if (selectedAgents.has(agent)) {
|
else if (selectedAgents.has(agent)) {
|
||||||
// Haetaan satunnainen "toinen agentti", johon viitata
|
if (agent === 'client') {
|
||||||
// Tehdään tästä deterministinen agentin nimen perusteella, ettei vilku
|
wrap.setAttribute('data-tooltip', `💬 ${agentTitle}: "Mietin parhaillani uusia vaatimuksia!\nPysykää kuulolla, kerron niistä Managerille."`);
|
||||||
const targets = {
|
} else if (agent === 'manager') {
|
||||||
client: 'Managerin',
|
wrap.setAttribute('data-tooltip', `💬 ${agentTitle}: "Käyn läpi asiakkaan toiveita.\nDelegoin uudet taskit pian Koodarille ja QA:lle!"`);
|
||||||
manager: 'Asiakkaan',
|
} else {
|
||||||
coder: 'DevOpsin',
|
const targets = { coder: 'DevOpsin', data: 'Koodarin', qa: 'Data-Agentin', tester: 'QA:n', observer: 'Managerin' };
|
||||||
data: 'Koodarin',
|
const targetName = targets[agent] || 'Koodarin';
|
||||||
qa: 'Data-Agentin',
|
wrap.setAttribute('data-tooltip', `💬 ${agentTitle}: "Hei, minäkin haluan osallistua!\nVoisin tehdä ${targetName} asiaan tällaisen toiminnallisuuden!"`);
|
||||||
tester: 'QA:n',
|
}
|
||||||
observer: 'Managerin'
|
|
||||||
};
|
|
||||||
const targetName = targets[agent] || 'Koodarin';
|
|
||||||
wrap.setAttribute('data-tooltip', `💬 ${agentTitle}: "Hei, minäkin haluan osallistua!\nVoisin tehdä ${targetName} asiaan tällaisen toiminnallisuuden!"`);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1321,6 +1318,97 @@
|
|||||||
// Tarkistetaan heti alussa
|
// Tarkistetaan heti alussa
|
||||||
setTimeout(checkAgentConfusion, 100);
|
setTimeout(checkAgentConfusion, 100);
|
||||||
|
|
||||||
|
// -- SIMULAATIO --
|
||||||
|
window.simulationInterval = null;
|
||||||
|
window.toggleSimulation = function() {
|
||||||
|
const btn = document.getElementById('simu-btn');
|
||||||
|
if (window.simulationInterval) {
|
||||||
|
clearInterval(window.simulationInterval);
|
||||||
|
window.simulationInterval = null;
|
||||||
|
if (btn) btn.textContent = 'Käynnistä simulaatio';
|
||||||
|
checkAgentConfusion(); // Palautetaan normaalitilat
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (btn) btn.textContent = 'Lopeta simulaatio';
|
||||||
|
const agentsList = Object.keys(agentPrompts);
|
||||||
|
|
||||||
|
window.simulationInterval = setInterval(() => {
|
||||||
|
// Ensin putsataan kaikkien state takaisin normaaliksi
|
||||||
|
document.querySelectorAll('.gallery-head-wrap').forEach(w => w.classList.remove('state-alert', 'state-question'));
|
||||||
|
document.querySelectorAll('.gallery-head').forEach(g => g.classList.remove('state-alert', 'state-question'));
|
||||||
|
checkAgentConfusion();
|
||||||
|
|
||||||
|
// Arvotaan reagointi (20% todennäköisyys ettei kukaan hälytä juuri nyt)
|
||||||
|
if (Math.random() < 0.2) return;
|
||||||
|
|
||||||
|
const randAgent = agentsList[Math.floor(Math.random() * agentsList.length)];
|
||||||
|
const wrap = document.getElementById('wrap-' + randAgent);
|
||||||
|
const gel = document.getElementById('gallery-' + randAgent);
|
||||||
|
const agentTitle = (agentPrompts[randAgent].name.split(' — ')[0] || "AGENTTI").toUpperCase();
|
||||||
|
|
||||||
|
if (wrap && gel) {
|
||||||
|
const isAlert = Math.random() > 0.5;
|
||||||
|
const cClass = isAlert ? 'state-alert' : 'state-question';
|
||||||
|
|
||||||
|
// Poistetaan "normaali" active, ettei tooltip jää alle, vaikkei tämä ehkä haittaisi
|
||||||
|
wrap.classList.remove('state-alert', 'state-question');
|
||||||
|
gel.classList.remove('state-alert', 'state-question');
|
||||||
|
|
||||||
|
wrap.classList.add(cClass);
|
||||||
|
gel.classList.add(cClass);
|
||||||
|
|
||||||
|
const simAlerts = {
|
||||||
|
client: `❗ ${agentTitle}: "🚨 Aikataulu on vaarassa!"\n(Simuloitu huoli: "Miksi luvattu ominaisuus ei ole vielä tuotannossa?")`,
|
||||||
|
manager: `❗ ${agentTitle}: "🚨 Tiimin kapasiteetti ylitetty!"\n(Simuloitu varoitus: "Tarvitaan lisäresursseja Koodari-Nodelle heti.")`,
|
||||||
|
coder: `❗ ${agentTitle}: "🚨 Kääntäjävirhe!"\n(Simuloitu ongelma: "Riippuvuuspuu hajosi viimeisimmän commitin jälkeen. Korjaan...")`,
|
||||||
|
data: `❗ ${agentTitle}: "🚨 Tietokannan lukko!"\n(Simuloitu poikkeama: "Taulussa 'users' on transaction deadlock. Terminoidaan kysely.")`,
|
||||||
|
qa: `❗ ${agentTitle}: "🚨 Regressio havaittu!"\n(Simuloitu löydös: "Testiautomaatio raportoi 3 rikkinäistä polkua. Palautetaan koodarille!")`,
|
||||||
|
tester: `❗ ${agentTitle}: "🚨 Node piiputtaa!"\n(Simuloitu hälytys: "WebAssembly-muistinkulutus 95%. Allokoidaan lisää resursseja.")`,
|
||||||
|
observer: `❗ ${agentTitle}: "🚨 Poikkeama protokollassa!"\n(Simuloitu valvojan ilmoitus: "Solmu palautti epäilyttävän vastauksen. Rajoitan oikeuksia.")`
|
||||||
|
};
|
||||||
|
|
||||||
|
const simQuestions = {
|
||||||
|
client: `❓ ${agentTitle}: "Saisimmeko tähän vielä yhden muutoksen?"\n(Simuloitu lisätoive: "Voisimmeko muuttaa napin värit hieman kirkkaammiksi?")`,
|
||||||
|
manager: `❓ ${agentTitle}: "Onko arkkitehtuuri jo valmis?"\n(Simuloitu kysely: "Laittakaa minulle päivitys rajapintojen tilanteesta.")`,
|
||||||
|
coder: `❓ ${agentTitle}: "Täsmennystä kaivataan..."\n(Simuloitu kysely: "Tehdäänkö tämä komponentti uudestaan vai hyödynnetäänkö vanhaa?")`,
|
||||||
|
data: `❓ ${agentTitle}: "Outo tietorakenne?"\n(Simuloitu utelu: "Miksi asiakkaan lähettämä JSON on formatoitu näin? Pyydän korjausta.")`,
|
||||||
|
qa: `❓ ${agentTitle}: "Puuttuvat testiolosuhteet?"\n(Simuloitu ihmettely: "Onko meillä valmista testidataa tälle skenaariolle?")`,
|
||||||
|
tester: `❓ ${agentTitle}: "Julkaisulupa?"\n(Simuloitu kysymys: "Docker-imaget ovat valmiina. Voidaanko painaa nappia?")`,
|
||||||
|
observer: `❓ ${agentTitle}: "Laatumetriikat uupuvat..."\n(Simuloitu huomio: "Mittaustulokset viiveestä eivät ole saapuneet vielä lokiin.")`
|
||||||
|
};
|
||||||
|
|
||||||
|
let textRaw = "";
|
||||||
|
let termColor = "";
|
||||||
|
if (isAlert) {
|
||||||
|
const txt = simAlerts[randAgent] || `❗ ${agentTitle}: "🚨 Hälytys verkossa!"`;
|
||||||
|
wrap.setAttribute('data-tooltip', txt);
|
||||||
|
textRaw = txt.replace(/\n\(/g, ' - ').replace(/\)/g, '');
|
||||||
|
termColor = '#ff4444';
|
||||||
|
} else {
|
||||||
|
const txt = simQuestions[randAgent] || `❓ ${agentTitle}: "Minulla olisi ehdotus..."`;
|
||||||
|
wrap.setAttribute('data-tooltip', txt);
|
||||||
|
textRaw = txt.replace(/\n\(/g, ' - ').replace(/\)/g, '');
|
||||||
|
termColor = '#58a6ff';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tulostetaan tapahtuma terminaaliin
|
||||||
|
if (typeof termLog === 'function') {
|
||||||
|
termLog(`<span style="color:${termColor}">[SIMULAATIO]</span> ${textRaw}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Häly kestää tasan 5 sekuntia, sitten palautuu normaaliksi
|
||||||
|
setTimeout(() => {
|
||||||
|
if (window.simulationInterval) {
|
||||||
|
wrap.classList.remove(cClass);
|
||||||
|
gel.classList.remove(cClass);
|
||||||
|
checkAgentConfusion();
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
}, 6000); // Tapahtuu 6 sekunnin välein
|
||||||
|
};
|
||||||
|
|
||||||
window.switchMainTab = function(tab) {
|
window.switchMainTab = function(tab) {
|
||||||
document.querySelectorAll('.main-panel').forEach(p => p.classList.remove('active'));
|
document.querySelectorAll('.main-panel').forEach(p => p.classList.remove('active'));
|
||||||
document.querySelectorAll('.main-tab').forEach(t => t.classList.remove('active'));
|
document.querySelectorAll('.main-tab').forEach(t => t.classList.remove('active'));
|
||||||
@@ -2449,7 +2537,7 @@
|
|||||||
|
|
||||||
const translations = {
|
const translations = {
|
||||||
fi: {
|
fi: {
|
||||||
main_title: "<span style=\"color:#ff6b00\">Kipinä</span> <span>Agent Dashboard</span>",
|
main_title: "<span style=\"color:#ff6b00\">Kipinä</span> <span>Agent Playground</span>",
|
||||||
main_subtitle: "Hajautettu WebGPU Laskentaverkko",
|
main_subtitle: "Hajautettu WebGPU Laskentaverkko",
|
||||||
tab_network: "Laskentaverkko",
|
tab_network: "Laskentaverkko",
|
||||||
tab_codelab: "Koodilaboratorio",
|
tab_codelab: "Koodilaboratorio",
|
||||||
@@ -2475,7 +2563,7 @@
|
|||||||
metric_uptime: "Käynnissä"
|
metric_uptime: "Käynnissä"
|
||||||
},
|
},
|
||||||
se: {
|
se: {
|
||||||
main_title: "<span style=\"color:#ff6b00\">Kipinä</span> <span>Agent Dashboard</span>",
|
main_title: "<span style=\"color:#ff6b00\">Kipinä</span> <span>Agent Playground</span>",
|
||||||
main_subtitle: "Decentraliserat WebGPU Beräkningsnätverk",
|
main_subtitle: "Decentraliserat WebGPU Beräkningsnätverk",
|
||||||
tab_network: "Kalkylnätverk",
|
tab_network: "Kalkylnätverk",
|
||||||
tab_codelab: "Kodlaboratorium",
|
tab_codelab: "Kodlaboratorium",
|
||||||
@@ -2501,7 +2589,7 @@
|
|||||||
metric_uptime: "Drifttid"
|
metric_uptime: "Drifttid"
|
||||||
},
|
},
|
||||||
en: {
|
en: {
|
||||||
main_title: "<span style=\"color:#ff6b00\">Kipinä</span> <span>Agent Dashboard</span>",
|
main_title: "<span style=\"color:#ff6b00\">Kipinä</span> <span>Agent Playground</span>",
|
||||||
main_subtitle: "Decentralized WebGPU Compute Network",
|
main_subtitle: "Decentralized WebGPU Compute Network",
|
||||||
tab_network: "Compute Network",
|
tab_network: "Compute Network",
|
||||||
tab_codelab: "Code Laboratory",
|
tab_codelab: "Code Laboratory",
|
||||||
|
|||||||
Reference in New Issue
Block a user