### 2. Valvomon kC$yttC6liittymC$n pC$ivitys (Kuvien renderC6inti)
Jotta sinC$ nC$et graafisessa Valvomossa saman kuvan kuin tekoC$ly (etkC$ vain
loputonta Base64-siansaksaa), meidC$n tC$ytyy opettaa Valvomon UI
nC$yttC$mC$C$n HTML:n `<img...>` -tC$gi.
Avaa `valvomo_proxy.py` ja korvaa selaimen `fetchData()`-funktion alkuosa
(`<script>` -tagin sisC$ltC$) tC$llC$ pC$tkC$llC$. Se tarkistaa onko sisC$ltC6
taulukko (kuten kuvallisissa pyynnC6issC$), kaivaa kuvan esiin ja piirtC$C$
sen ruudulle.
```javascript
// Hae Prompts
let pRes = await fetch('/valvomo/prompts/pending');
let prompts = await pRes.json();
let pHTML = '';
for (let [id, data] of Object.entries(prompts)) {
// Parsitaan visuaalinen payload nC$tiksi HTML:ksi
let messages = data.request.messages.map(m => {
if (Array.isArray(m.content)) {
let textPart = m.content.find(c => c.type ===
'text')?.text || '';
let imgPart = m.content.find(c => c.type ===
'image_url')?.image_url?.url;
let imgTag = imgPart ? `<br><img src="${imgPart}"
style="max-width: 100%; max-height: 300px; border: 1px solid #555; margin-top:
10px; border-radius: 4px;">` : '';
return `[${m.role}] ${textPart} ${imgTag}`;
} else {
return `[${m.role}] ${m.content}`;
}
}).join('<br><br>');
pHTML += `
<div class="card">
<small>ID: ${id}</small>
<div style="background: #1e1e1e; padding: 10px;
border-radius: 4px; overflow-x: auto; margin-bottom: 10px;">${messages}</div>
<textarea id="manual-${id}" placeholder="Kirjoita
manuaalinen vastaus tC$hC$n..." rows="2"></textarea>
<button class="success" onclick="act('/valvomo/prom
pts/${id}/approve', 'POST')">ReititC$ LLM:lle</button>
<button onclick="manualAnswer('${id}')">Anna
Vastaus</button>
<button class="danger" onclick="act('/valvomo/promp
ts/${id}/reject', 'POST')">HylkC$C$</button>
</div>
`;
}
document.getElementById('prompts-container').innerHTML = pHTML
|| '<p>Ei odottavia prompteja.</p>';
```
KC$ynnistC$ proxy uudelleen (`Ctrl+C` -> `uvicorn valvomo_proxy:app ...`) ja
aja uusi `test_valvomo.py`.
Nyt Valvomoon napsahtaa kysely, jossa nC$et suoraan kysytyn asian **ja kuvan,
jota LLM on aikeissa analysoida**. TC$mC$ antaa sinulle tC$yden kontekstin
siihen, voiko malli ylipC$C$tC$C$n ratkaista ongelman, ennen kuin edes
reititC$t sitC$ klusterillesi.