Skip to content

Instantly share code, notes, and snippets.

@DimDevOff
Created October 3, 2025 07:18
Show Gist options
  • Select an option

  • Save DimDevOff/273d6a095cfcf90907d63ff3280a04c1 to your computer and use it in GitHub Desktop.

Select an option

Save DimDevOff/273d6a095cfcf90907d63ff3280a04c1 to your computer and use it in GitHub Desktop.
InfWiki.html
<!DOCTYPE html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<title>Нескінченна Вікі: Chat Ollama</title>
<style>
body { font-family: Arial, sans-serif; background: #f6f7fa; margin: 0; padding: 2em;}
.wiki-block { background: #fff; padding: 1em 2em; border-radius: 8px; box-shadow: 0 4px 14px rgba(0,0,0,0.08); margin-bottom: 2em;}
.word-link { color: #0b67fc; cursor: pointer; text-decoration: underline; }
.loading { color: #888; }
.error { color: red; font-weight: bold; }
</style>
</head>
<body>
<div id="wiki-container"></div>
<script>
async function fetchWikiChatStream(topic, onChunk, onDone, onError) {
try {
const response = await fetch('http://127.0.0.1:11434/api/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model: "gemma3:270m",
prompt: `Напиши вікі про "${topic}". На Українській`,
stream: true
})
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
let fullText = "";
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = decoder.decode(value, { stream: true });
const lines = text.split('\n').filter(line => line.trim() !== '');
for (const line of lines) {
try {
const json = JSON.parse(line);
if (json.response) {
fullText += json.response;
if (onChunk) onChunk(fullText);
}
if (json.done) {
if (onDone) onDone(fullText);
return;
}
} catch (e) { /* пропуск помилок парсингу */ }
}
}
} catch(e) {
if(onError) onError(e);
}
}
function renderWordsAsLinks(text) {
return text
.split(/\s+/)
.map(word => {
const pure = word.replace(/[.,:;!?()\[\]«»"'-]+$/g, '');
if (!pure) return word;
return `<span class="word-link" onclick="event.preventDefault(); renderWiki('${pure.replace(/'/g,"\\'")}')">${word}</span>`;
})
.join(' ');
}
async function renderWiki(topic = "Життя") {
const container = document.getElementById('wiki-container');
const blockDiv = document.createElement('div');
blockDiv.className = 'wiki-block';
blockDiv.innerHTML = `<div class="loading">Генеруємо вікі про <b>${topic}</b>...</div>`;
container.appendChild(blockDiv);
fetchWikiChatStream(topic,
(runningText) => { // onChunk
blockDiv.innerHTML = `<h2>${topic}</h2><p>${renderWordsAsLinks(runningText)}</p>`;
},
(finalText) => { // onDone
blockDiv.innerHTML = `<h2>${topic}</h2><p>${renderWordsAsLinks(finalText)}</p>`;
},
(err) => { // onError
blockDiv.innerHTML = `<span class="error">Помилка при генерації вікі: ${err.message}</span>`;
}
);
}
window.renderWiki = renderWiki; // для onclick
renderWiki("Життя");
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment