client side for the win!

rendering llm markdown as html
This commit is contained in:
root 2024-10-19 16:22:33 +00:00
parent afce79f776
commit 880c09bc86

View file

@ -24,6 +24,9 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/styles/a11y-dark.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js"></script>
<!-- Needed by LLM to do realtime markdown rendering into HTML -->
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<!-- Theme Switcher Script -->
<script>
function switchTheme(theme) {
@ -199,6 +202,151 @@ pip install vllm
python -m vllm.entrypoints.openai.api_server --model NousResearch/Hermes-3-Llama-3.1-8B --host 0.0.0.0 --port 18888 --max-model-len 16000
</code></pre>
<h2 id="client-side">Client Side Only Example, chat with this page.</h2>
<p>view page source, it's _all_ there!</p>
<div id="chat-container">
<div id="chat-box"></div>
<div></div>
</div>
<div>
<input type="text" id="user-input" placeholder="Ask about this page...">
<button onclick="handleUserInput()">Send</button>
</div>
<script>
// LLM Webpage Client
// Configuration
const API_URL = "https://hermes.ai.unturf.com/v1/chat/completions";
const API_KEY = "dummy-api-key";
const MODEL = "NousResearch/Hermes-3-Llama-3.1-8B";
// Initialize chat history
let chatHistory = [
{
role: "system",
content: "You are an AI assistant embedded in a webpage. Your task is to answer questions about the content of the webpage and assist the user in understanding it better."
}
];
// Function to extract text content from the webpage
function extractWebpageContent() {
return document.body.innerText;
}
// Generator function to send a message to the LLM and yield responses
async function* sendMessage(message) {
chatHistory.push({ role: "user", content: message });
const response = await fetch(API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_KEY}`
},
body: JSON.stringify({
model: MODEL,
messages: chatHistory,
temperature: 0.5,
max_tokens: 5600,
stream: true
})
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n');
for (let i = 0; i < lines.length - 1; i++) {
const line = lines[i].trim();
if (line.startsWith('data: ')) {
const jsonData = line.slice(6);
if (jsonData === '[DONE]') continue;
try {
const parsedData = JSON.parse(jsonData);
const content = parsedData.choices[0].delta.content;
if (content) {
yield content;
}
} catch (error) {
console.error('Error parsing JSON:', error);
}
}
}
buffer = lines[lines.length - 1];
}
}
// Function to handle user input and display responses
async function handleUserInput() {
const userInput = document.getElementById('user-input').value;
document.getElementById('user-input').value = '';
const chatBox = document.getElementById('chat-box');
chatBox.innerHTML += `<p><strong>You:</strong> ${userInput}</p>`;
chatBox.innerHTML += `<p><strong>AI:</strong> `;
const messageElement = chatBox.lastElementChild;
let accumulatedContent = '';
for await (const chunk of sendMessage(userInput)) {
accumulatedContent += chunk;
const parsedChunk = marked.parse(accumulatedContent);
messageElement.innerHTML = parsedChunk;
// Apply syntax highlighting to code blocks
messageElement.querySelectorAll('pre code').forEach((block) => {
hljs.highlightElement(block);
});
}
chatBox.scrollTop = chatBox.scrollHeight;
}
// Function to initialize the chat interface
function initializeChatInterface() {
const pageContent = extractWebpageContent();
chatHistory.push({
role: "system",
content: `Here's the content of the webpage: ${pageContent}`
});
// Set up marked.js options
marked.setOptions({
highlight: function(code, lang) {
const language = hljs.getLanguage(lang) ? lang : 'plaintext';
return hljs.highlight(code, { language }).value;
}
});
}
document.getElementById("user-input").addEventListener("keypress", function(event) {
if (event.key === "Enter") {
event.preventDefault();
handleUserInput();
}
});
// Initialize the chat interface when the page loads
window.onload = initializeChatInterface;
// Expose handleUserInput to the global scope
window.handleUserInput = handleUserInput;
</script>
<h2>Questions, Comments, Discussions</h2>
<div id="remarkbox-div">
<noscript>