Mermaid-kaaviot oppaaseen + mallitiedot agents-sivun status-palkkiin

GUIDE.md:n ASCII-kaaviot korvattu Mermaid-kaavioilla:
- Projekti-pipeline: flowchart TD värikoodatuilla vaiheilla
- Prompttirakenne: system → agent → user → prefill ketju

Mermaid ladataan CDN:stä ja renderöidään automaattisesti dark-teemalla.
Fallback: kaavion lähdekoodi näkyy tekstinä jos Mermaid ei lataudu.

Agents-sivun compute-status näyttää nyt tarkan mallitiedon:
- "Qwen2.5-Coder-0.5B" tai "Qwen2.5-Coder-3B"
- Tooltip: parametrimäärä, runtime, max tokenit

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jaakko Vanhala
2026-04-06 08:23:19 +03:00
parent dd1945ab28
commit 176f2d6915
2 changed files with 45 additions and 60 deletions

View File

@@ -73,31 +73,20 @@ vaan **mallin kyky ymmärtää pitkää kontekstia** — 0.5B-malli alkaa
### Kolmitasoinen prompttirakenne ### Kolmitasoinen prompttirakenne
``` ```mermaid
┌─ System prompt (kiinteä, kovakoodattu) ─────────────────────┐ flowchart TD
│ "You are a coding assistant. Respond with ONLY code." │ S["System prompt<br/><i>You are a coding assistant. Respond with ONLY code.</i><br/>🔒 Kiinteä, kovakoodattu — malli priorisoi tämän"]
│ → Määrittää mallin roolin ja rajoitteet │ A["Agent prompt<br/><i>Olet kokenut ohjelmistokehittäjä...</i><br/>✏️ Käyttäjän muokattavissa UI:ssa"]
│ → Tämä on tehokkain ohje koska malli priorisoi sen │ U["User prompt<br/><i>Write ONLY the file main.py...</i><br/>📋 Vaihtelee joka kutsussa, sisältää kontekstin"]
└─────────────────────────────────────────────────────────────┘ P["Prefill: ``` <br/>🎯 Pakottaa mallin aloittamaan koodilla"]
S --> A --> U --> P
┌─ Agent prompt (käyttäjän muokattavissa) ────────────────────┐ P -->|malli jatkaa| R["Generoitu koodi"]
│ "Olet kokenut ohjelmistokehittäjä. Kirjoita selkeää..." │
│ → Agenttikohtainen persoonallisuus ja erikoisosaaminen │ style S fill:#1a1e2e,stroke:#f85149,color:#c9d1d9
│ → Tallennetaan localStorageen, voi muokata UI:ssa │ style A fill:#1a1e2e,stroke:#d29922,color:#c9d1d9
└─────────────────────────────────────────────────────────────┘ style U fill:#1a1e2e,stroke:#3fb950,color:#c9d1d9
style P fill:#1a1e2e,stroke:#a371f7,color:#c9d1d9
┌─ User prompt (vaihtelee joka kutsussa) ─────────────────────┐ style R fill:#0d1117,stroke:#58a6ff,color:#58a6ff
│ "Write ONLY the file main.py: FastAPI app with endpoints." │
│ → Konkreettinen tehtävä tällä kerralla │
│ → Sisältää kontekstin (aiemmat tiedostot) pipeline-tilassa │
└─────────────────────────────────────────────────────────────┘
┌─ Prefill (pakottaa vastausformaatin) ───────────────────────┐
│ ``` │
│ → Malli luulee aloittaneensa koodiblokin ja jatkaa koodilla │
│ → Estää "Sure! Here is..." -johdantotekstit │
│ → Säästää ~10-20 tokenia per vastaus │
└─────────────────────────────────────────────────────────────┘
``` ```
### Miksi promptit ovat englanniksi? ### Miksi promptit ovat englanniksi?
@@ -207,38 +196,17 @@ stop-kohtaan.
## Projekti-pipeline — miten agenttitiimi toimii ## Projekti-pipeline — miten agenttitiimi toimii
``` ```mermaid
┌──────────┐ flowchart TD
Käyttäjä │ "FastAPI + SQLite REST API for users" U["Käyttäjä: FastAPI + SQLite REST API for users"] --> M
└────┬─────┘ M["🟡 Manageri: Pilko tiedostoiksi"] -->|tiedostolista| C1
C1["🟢 Koodari: models.py"] -->|"konteksti: models.py"| C2
┌──────────┐ "Pilko tiedostoiksi" C2["🟢 Koodari: main.py"] -->|"konteksti: models + main"| C3
│ Manageri │ → models.py, main.py, pyproject.toml C3["🟢 Koodari: pyproject.toml"] -->|kaikki tiedostot| T1
└────┬─────┘ T1["🔵 Testaaja: Review"] -->|bugeja löytyi| C4
↓ (tiedostolista) T1 -->|LGTM| Done["✅ Projekti valmis"]
┌──────────┐ "Kirjoita models.py" C4["🟡 Koodari: Korjaukset"] --> T2
│ Koodari │ → from sqlalchemy import ... T2["🔵 Testaaja: Uudelleenarviointi"] --> Done
└────┬─────┘
↓ (models.py kontekstina)
┌──────────┐ "Kirjoita main.py, käytä models.py:tä"
│ Koodari │ → from fastapi import ...
└────┬─────┘
↓ (kaikki tiedostot kontekstina)
┌──────────┐ "Kirjoita pyproject.toml"
│ Koodari │ → [project] dependencies = [...]
└────┬─────┘
↓ (kaikki tiedostot yhdessä)
┌──────────┐ "Review: onko bugeja?"
│ Testaaja │ → "Missing db.close(), no error handling"
└────┬─────┘
↓ (review-palaute + koodi)
┌──────────┐ "Korjaa nämä ongelmat"
│ Koodari │ → Korjattu koodi
└────┬─────┘
┌──────────┐ "Tarkista korjaukset"
│ Testaaja │ → "LGTM" tai lisäkorjauksia
└──────────┘
``` ```
**Kontekstin ketjutus** on kriittistä: kun koodari kirjoittaa `main.py`:tä, **Kontekstin ketjutus** on kriittistä: kun koodari kirjoittaa `main.py`:tä,

View File

@@ -6,6 +6,7 @@
<title>Kipinä Agentic Playground</title> <title>Kipinä Agentic Playground</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github-dark.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github-dark.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js"></script>
<style> <style>
:root { :root {
--bg-color: #0d1117; --bg-color: #0d1117;
@@ -3155,7 +3156,8 @@ Write the corrected code.`;
const cl = document.getElementById('agent-compute-label'); const cl = document.getElementById('agent-compute-label');
const btn = document.getElementById('agent-compute-btn'); const btn = document.getElementById('agent-compute-btn');
if (cd) cd.style.background = '#3fb950'; if (cd) cd.style.background = '#3fb950';
if (cl) { cl.textContent = 'Qwen2.5-Coder'; cl.style.color = '#3fb950'; } const sizeLabel = coderSize === '3b' ? '3B (3 miljardia parametria)' : '0.5B (500 miljoonaa parametria)';
if (cl) { cl.textContent = 'Qwen2.5-Coder-' + (coderSize === '3b' ? '3B' : '0.5B'); cl.style.color = '#3fb950'; cl.title = sizeLabel + ' · Candle Wasm · CPU · max 512 tok'; }
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'); localStorage.setItem('kpn-coder-loaded', 'true');
} }
@@ -3492,6 +3494,16 @@ Write the corrected code.`;
container.querySelectorAll('pre code').forEach(block => { container.querySelectorAll('pre code').forEach(block => {
if (typeof hljs !== 'undefined') hljs.highlightElement(block); if (typeof hljs !== 'undefined') hljs.highlightElement(block);
}); });
// Mermaid-kaaviot
if (typeof mermaid !== 'undefined') {
mermaid.initialize({ startOnLoad: false, theme: 'dark', themeVariables: { primaryColor: '#58a6ff', primaryTextColor: '#c9d1d9', lineColor: '#30363d', background: '#0d1117' } });
container.querySelectorAll('.mermaid-container').forEach(async el => {
try {
const { svg } = await mermaid.render('m-' + el.id, el.textContent.trim());
el.innerHTML = svg;
} catch(e) { /* fallback: jätetään teksti näkyviin */ }
});
}
} catch(e) { } catch(e) {
container.innerHTML = '<p style="color:#f85149">Virhe: ' + e.message + '</p>'; container.innerHTML = '<p style="color:#f85149">Virhe: ' + e.message + '</p>';
} }
@@ -3532,10 +3544,15 @@ Write the corrected code.`;
} }
for (const line of lines) { for (const line of lines) {
// Koodiblokit // Koodiblokit + Mermaid-kaaviot
if (line.startsWith('```')) { if (line.startsWith('```')) {
if (inCode) { if (inCode) {
if (codeLang === 'mermaid') {
const mermaidId = 'mermaid-' + Math.random().toString(36).slice(2, 8);
html += `<div class="mermaid-container" id="${mermaidId}" style="margin:16px 0;text-align:center">${codeBuffer.replace(/</g,'&lt;')}</div>`;
} else {
html += `<pre style="background:#0d1117;border:1px solid #30363d;border-radius:6px;padding:14px;margin:12px 0;overflow-x:auto"><code class="language-${codeLang}">${codeBuffer.replace(/</g,'&lt;')}</code></pre>`; html += `<pre style="background:#0d1117;border:1px solid #30363d;border-radius:6px;padding:14px;margin:12px 0;overflow-x:auto"><code class="language-${codeLang}">${codeBuffer.replace(/</g,'&lt;')}</code></pre>`;
}
inCode = false; inCode = false;
codeBuffer = ''; codeBuffer = '';
} else { } else {