|
|
|
@@ -1491,12 +1491,19 @@
|
|
|
|
let detectedWebGPU = false;
|
|
|
|
let detectedWebGPU = false;
|
|
|
|
let detectedGpuInfo = null;
|
|
|
|
let detectedGpuInfo = null;
|
|
|
|
let wasmInitialized = false;
|
|
|
|
let wasmInitialized = false;
|
|
|
|
let coderSize = '05b'; // '05b' tai '3b'
|
|
|
|
let coderSize = localStorage.getItem('kpn-coder-size') || '05b';
|
|
|
|
|
|
|
|
|
|
|
|
// Mallivalinnan radio-napit
|
|
|
|
// Mallivalinnan radio-napit — asetetaan oikea valinta localStoragesta
|
|
|
|
|
|
|
|
const savedRadio = document.querySelector(`input[name="coder-size"][value="${coderSize}"]`);
|
|
|
|
|
|
|
|
if (savedRadio) savedRadio.checked = true;
|
|
|
|
|
|
|
|
if (coderSize === '3b') {
|
|
|
|
|
|
|
|
document.getElementById('coder-opt-05b')?.style && (document.getElementById('coder-opt-05b').style.borderColor = 'var(--border-color)');
|
|
|
|
|
|
|
|
document.getElementById('coder-opt-3b')?.style && (document.getElementById('coder-opt-3b').style.borderColor = 'var(--accent-color)');
|
|
|
|
|
|
|
|
}
|
|
|
|
document.querySelectorAll('input[name="coder-size"]').forEach(radio => {
|
|
|
|
document.querySelectorAll('input[name="coder-size"]').forEach(radio => {
|
|
|
|
radio.addEventListener('change', (e) => {
|
|
|
|
radio.addEventListener('change', (e) => {
|
|
|
|
coderSize = e.target.value;
|
|
|
|
coderSize = e.target.value;
|
|
|
|
|
|
|
|
localStorage.setItem('kpn-coder-size', coderSize);
|
|
|
|
// Visuaalinen korostus
|
|
|
|
// Visuaalinen korostus
|
|
|
|
document.getElementById('coder-opt-05b').style.borderColor = coderSize === '05b' ? 'var(--accent-color)' : 'var(--border-color)';
|
|
|
|
document.getElementById('coder-opt-05b').style.borderColor = coderSize === '05b' ? 'var(--accent-color)' : 'var(--border-color)';
|
|
|
|
document.getElementById('coder-opt-3b').style.borderColor = coderSize === '3b' ? 'var(--accent-color)' : 'var(--border-color)';
|
|
|
|
document.getElementById('coder-opt-3b').style.borderColor = coderSize === '3b' ? 'var(--accent-color)' : 'var(--border-color)';
|
|
|
|
@@ -1849,14 +1856,37 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (sub === 'load') {
|
|
|
|
if (sub === 'load') {
|
|
|
|
|
|
|
|
const arg = parts[2];
|
|
|
|
const btn = document.getElementById('agent-compute-btn');
|
|
|
|
const btn = document.getElementById('agent-compute-btn');
|
|
|
|
if (btn && btn.dataset.state === 'ready') {
|
|
|
|
// Mallikatalogista valinta numerolla tai nimellä
|
|
|
|
termLog(' ✓ Kielimalli on jo ladattu ja valmis', '#3fb950');
|
|
|
|
const loadModels = [
|
|
|
|
} else {
|
|
|
|
{ id: '1', key: '05b', name: 'Qwen2.5-Coder:0.5B', size: '~990 MB', coderSize: '05b' },
|
|
|
|
termLog(' Alustetaan laskentasolmua...', '#d29922');
|
|
|
|
{ id: '2', key: '3b', name: 'Qwen2.5-Coder:3B', size: '~6.2 GB', coderSize: '3b' },
|
|
|
|
if (btn) btn.click(); // Käytetään samaa logiikkaa kuin napissa
|
|
|
|
];
|
|
|
|
else ensureCoderNode();
|
|
|
|
if (!arg) {
|
|
|
|
|
|
|
|
// Näytetään lista
|
|
|
|
|
|
|
|
termLog(' Ladattavat mallit:', '#c9d1d9');
|
|
|
|
|
|
|
|
for (const m of loadModels) {
|
|
|
|
|
|
|
|
const active = (btn?.dataset.state === 'ready' && coderSize === m.coderSize) ? ' <span style="color:#3fb950">✓ ladattu</span>' : '';
|
|
|
|
|
|
|
|
termLog(` <span style="color:#58a6ff">${m.id}</span> ${m.name} <span style="color:#8b949e">(${m.size})</span>${active}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
termLog(' Käyttö: kpn load <numero>', '#8b949e');
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const selected = loadModels.find(m => m.id === arg || m.key === arg || m.coderSize === arg);
|
|
|
|
|
|
|
|
if (!selected) {
|
|
|
|
|
|
|
|
termLog(` Tuntematon malli "${esc(arg)}". Kokeile: kpn load`, '#f85149');
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (btn?.dataset.state === 'ready' && coderSize === selected.coderSize) {
|
|
|
|
|
|
|
|
termLog(` ✓ ${selected.name} on jo ladattu ja valmis`, '#3fb950');
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
coderSize = selected.coderSize;
|
|
|
|
|
|
|
|
localStorage.setItem('kpn-coder-size', coderSize);
|
|
|
|
|
|
|
|
termLog(` Alustetaan ${selected.name} (${selected.size})...`, '#d29922');
|
|
|
|
|
|
|
|
if (btn) btn.click();
|
|
|
|
|
|
|
|
else ensureCoderNode();
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1868,11 +1898,14 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (sub === 'models') {
|
|
|
|
if (sub === 'models') {
|
|
|
|
termLog(' smollm-135m — SmolLM 135M (kevyt)', '#a5d6ff');
|
|
|
|
termLog(' Käytettävissä olevat mallit:', '#c9d1d9');
|
|
|
|
termLog(' qwen-05b — Qwen2.5 0.5B', '#a5d6ff');
|
|
|
|
termLog(' <span style="color:#58a6ff">1</span> qwen-coder Qwen2.5-Coder:0.5B <span style="color:#8b949e">~990 MB | koodin generointi</span>');
|
|
|
|
termLog(' phi3-mini — Phi-3 Mini', '#a5d6ff');
|
|
|
|
termLog(' <span style="color:#58a6ff">2</span> qwen-coder-3b Qwen2.5-Coder:3B <span style="color:#8b949e">~6.2 GB | parempi koodinlaatu</span>');
|
|
|
|
termLog(' qwen-coder — Qwen2.5-Coder 0.5B', '#a5d6ff');
|
|
|
|
termLog(' <span style="color:#58a6ff">3</span> smollm-135m SmolLM 135M <span style="color:#8b949e">~270 MB | kevyt, nopea</span>');
|
|
|
|
termLog(' qwen-coder-3b — Qwen2.5-Coder 3B', '#a5d6ff');
|
|
|
|
termLog(' <span style="color:#58a6ff">4</span> qwen-05b Qwen2.5:0.5B <span style="color:#8b949e">~990 MB | yleismalli</span>');
|
|
|
|
|
|
|
|
termLog(' <span style="color:#58a6ff">5</span> phi3-mini Phi-3 Mini <span style="color:#8b949e">~2.2 GB | Microsoftin malli</span>');
|
|
|
|
|
|
|
|
termLog(' Käyttö: kpn run <malli> "<prompti>"', '#8b949e');
|
|
|
|
|
|
|
|
termLog(' Lataus: kpn load <numero>', '#8b949e');
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1905,7 +1938,9 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Jos käyttäjä syötti agentin nimen (esim. "coder"), vaihdetaan se oikeaksi tekoälymalliksi ("qwen-coder")
|
|
|
|
// Jos käyttäjä syötti agentin nimen (esim. "coder"), vaihdetaan se oikeaksi tekoälymalliksi ("qwen-coder")
|
|
|
|
if (agentPrompts[model]) {
|
|
|
|
if (model === 'coder-3b') {
|
|
|
|
|
|
|
|
model = 'qwen-coder-3b';
|
|
|
|
|
|
|
|
} else if (agentPrompts[model]) {
|
|
|
|
model = agentPrompts[model].model;
|
|
|
|
model = agentPrompts[model].model;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1919,12 +1954,14 @@
|
|
|
|
// Tab-completion: ennustava komennonsyöttö sana kerrallaan
|
|
|
|
// Tab-completion: ennustava komennonsyöttö sana kerrallaan
|
|
|
|
const kpnCommands = {
|
|
|
|
const kpnCommands = {
|
|
|
|
'kpn': ['help', 'run', 'pipeline', 'load', 'status', 'models', 'hello', 'clear'],
|
|
|
|
'kpn': ['help', 'run', 'pipeline', 'load', 'status', 'models', 'hello', 'clear'],
|
|
|
|
'kpn run': ['coder', 'manager', 'tester', 'qa', 'data', 'observer', 'qwen-coder', 'smollm-135m', 'qwen-05b', 'phi3-mini'],
|
|
|
|
'kpn run': ['coder', 'coder-3b', 'manager', 'tester', 'qa', 'data', 'observer', 'qwen-coder', 'qwen-coder-3b', 'smollm-135m', 'qwen-05b', 'phi3-mini'],
|
|
|
|
|
|
|
|
'kpn load': ['1', '2'],
|
|
|
|
'kpn pipeline': ['"'],
|
|
|
|
'kpn pipeline': ['"'],
|
|
|
|
};
|
|
|
|
};
|
|
|
|
// Esimerkkipromptit malleittain
|
|
|
|
// Esimerkkipromptit malleittain
|
|
|
|
const kpnExamples = {
|
|
|
|
const kpnExamples = {
|
|
|
|
'kpn run coder': ['"hello world in python"', '"fibonacci in rust"', '"quicksort in javascript"'],
|
|
|
|
'kpn run coder': ['"hello world in python"', '"fibonacci in rust"', '"quicksort in javascript"'],
|
|
|
|
|
|
|
|
'kpn run coder-3b': ['"binary search tree in rust"', '"REST API with Flask"', '"async web scraper in python"'],
|
|
|
|
'kpn run manager': ['"suunnittele REST API"', '"priorisoi tiimin tehtävät"'],
|
|
|
|
'kpn run manager': ['"suunnittele REST API"', '"priorisoi tiimin tehtävät"'],
|
|
|
|
'kpn run tester': ['"testaa login-toiminto"'],
|
|
|
|
'kpn run tester': ['"testaa login-toiminto"'],
|
|
|
|
'kpn pipeline': ['"rakenna todo-sovellus"', '"tee laskin pythonilla"'],
|
|
|
|
'kpn pipeline': ['"rakenna todo-sovellus"', '"tee laskin pythonilla"'],
|
|
|
|
@@ -2747,6 +2784,7 @@
|
|
|
|
if (cd) cd.style.background = '#3fb950';
|
|
|
|
if (cd) cd.style.background = '#3fb950';
|
|
|
|
if (cl) { cl.textContent = 'Qwen2.5-Coder'; cl.style.color = '#3fb950'; }
|
|
|
|
if (cl) { cl.textContent = 'Qwen2.5-Coder'; cl.style.color = '#3fb950'; }
|
|
|
|
if (btn) { btn.dataset.state = 'ready'; btn.textContent = '✓ Valmis'; btn.style.borderColor = '#3fb950'; btn.style.color = '#3fb950'; btn.style.cursor = 'default'; btn.title = 'Kielimalli ladattu — oma kone on valmis laskentaan'; }
|
|
|
|
if (btn) { btn.dataset.state = 'ready'; btn.textContent = '✓ Valmis'; btn.style.borderColor = '#3fb950'; btn.style.color = '#3fb950'; btn.style.cursor = 'default'; btn.title = 'Kielimalli ladattu — oma kone on valmis laskentaan'; }
|
|
|
|
|
|
|
|
localStorage.setItem('kpn-coder-loaded', 'true');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (msg.includes('[Coder]') && msg.includes('Syöte:')) {
|
|
|
|
if (msg.includes('[Coder]') && msg.includes('Syöte:')) {
|
|
|
|
// Pipeline piiloon kun generointi alkaa
|
|
|
|
// Pipeline piiloon kun generointi alkaa
|
|
|
|
@@ -2833,7 +2871,11 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Agents-sivun coder-node käynnistetään "Alusta laskentasolmu" -napista tai kpn load -komennolla
|
|
|
|
// Automaattinen uudelleenkäynnistys: jos malli oli ladattu ennen refreshiä, ladataan se uudelleen cachesta
|
|
|
|
|
|
|
|
if (localStorage.getItem('kpn-coder-loaded') === 'true') {
|
|
|
|
|
|
|
|
// Pieni viive jotta UI ehtii piirtyä
|
|
|
|
|
|
|
|
setTimeout(() => ensureCoderNode(), 500);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Laskentasolmun käynnistys/pysäytys -nappi
|
|
|
|
// Laskentasolmun käynnistys/pysäytys -nappi
|
|
|
|
let computeAbortController = null;
|
|
|
|
let computeAbortController = null;
|
|
|
|
|