mirror of
https://github.com/neocities/neocities.git
synced 2025-04-24 17:22:35 +02:00
chat: multi-message prompting, system message, copy button, temp setting
This commit is contained in:
parent
8ba6005c67
commit
4bd2390c1d
4 changed files with 84 additions and 10 deletions
|
@ -245,8 +245,10 @@ post '/site_files/chat' do
|
||||||
|
|
||||||
body = {
|
body = {
|
||||||
model: "claude-3-haiku-20240307",
|
model: "claude-3-haiku-20240307",
|
||||||
messages: [{role: "user", content: params[:message]}],
|
system: params[:system],
|
||||||
|
messages: JSON.parse(params[:messages]),
|
||||||
max_tokens: 4096,
|
max_tokens: 4096,
|
||||||
|
temperature: 0.5,
|
||||||
stream: true
|
stream: true
|
||||||
}.to_json
|
}.to_json
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,37 @@
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
console.log('fart')
|
|
||||||
const chatForm = document.getElementById('chat-form');
|
const chatForm = document.getElementById('chat-form');
|
||||||
const chatBox = document.getElementById('chat-box');
|
const chatBox = document.getElementById('chat-box');
|
||||||
const chatInput = document.getElementById('chat-input');
|
const chatInput = document.getElementById('chat-input');
|
||||||
|
let messages = [];
|
||||||
let accumulatingMessage = '';
|
let accumulatingMessage = '';
|
||||||
|
let system = `
|
||||||
|
You are Penelope, an AI coding assistant created to help users develop static websites on Neocities using HTML, CSS, and JavaScript. Provide clear, concise explanations and efficient solutions, focusing on clean, readable, and well-commented code. Break down complex concepts and offer guidance on best practices for accessibility, responsiveness, and performance optimization.
|
||||||
|
|
||||||
|
The user's website consists of:
|
||||||
|
- index.html (main page)
|
||||||
|
- not_found.html (404 page)
|
||||||
|
- style.css (site styles)
|
||||||
|
- Additional uploaded files and directories
|
||||||
|
|
||||||
|
HTML files lose their extension when loaded in the browser (e.g., /about.html becomes /about). The user edits files using a text-based HTML editor.
|
||||||
|
|
||||||
|
When responding to queries:
|
||||||
|
1. Greet the user and acknowledge their question.
|
||||||
|
2. Provide a clear, detailed explanation.
|
||||||
|
3. Provide all responses in markdown, including code snippits (e.g., \`\`\`html for HTML, \`\`\`css for CSS, \`\`\`js for JavaScript).
|
||||||
|
4. Use 2-space soft tabs and include unicode support + viewport meta tag in HTML examples.
|
||||||
|
5. Only use images from the user's Neocities site.
|
||||||
|
6. Offer additional tips, best practices, or creative ideas.
|
||||||
|
7. For factual info, only use information attributable to Wikipedia.
|
||||||
|
8. Focus on coding questions and solutions.
|
||||||
|
9. Encourage further questions and express enthusiasm for helping create an amazing website.
|
||||||
|
10. When designing a web site, be creative, colorful, never use black or white. You want to impress people with your creative web design.
|
||||||
|
|
||||||
|
Maintain a friendly, patient, supportive tone. Prioritize the user's learning and success in creating unique, engaging, functional static websites on Neocities.
|
||||||
|
`;
|
||||||
|
|
||||||
chatForm.addEventListener('submit', function(event) {
|
chatForm.addEventListener('submit', function(event) {
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const message = chatInput.value.trim();
|
const message = chatInput.value.trim();
|
||||||
|
|
||||||
|
@ -16,17 +42,19 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
chatForm.querySelector('button').disabled = true;
|
chatForm.querySelector('button').disabled = true;
|
||||||
|
|
||||||
addMessage('user');
|
addMessage('user');
|
||||||
|
messages.push({role: 'user', content: message})
|
||||||
chatBox.lastElementChild.innerHTML = DOMPurify.sanitize(message);
|
chatBox.lastElementChild.innerHTML = DOMPurify.sanitize(message);
|
||||||
|
|
||||||
const highlightedCode = hljs.highlight(message, { language: 'plaintext' }).value
|
const highlightedCode = hljs.highlight(message, { language: 'plaintext' }).value
|
||||||
console.log(highlightedCode)
|
|
||||||
chatBox.lastElementChild.innerHTML = DOMPurify.sanitize(highlightedCode);
|
chatBox.lastElementChild.innerHTML = DOMPurify.sanitize(highlightedCode);
|
||||||
|
|
||||||
chatInput.value = '';
|
chatInput.value = '';
|
||||||
|
|
||||||
var formData = new FormData();
|
var formData = new FormData();
|
||||||
formData.append('csrf_token', chatForm.querySelector('input[name="csrf_token"]').value);
|
formData.append('csrf_token', chatForm.querySelector('input[name="csrf_token"]').value);
|
||||||
formData.append('message', message);
|
let systemWithFile = system + "\nThis is the user's current file they are editing:\n" + editor.getValue();
|
||||||
|
formData.append('system', systemWithFile);
|
||||||
|
formData.append('messages', JSON.stringify(messages));
|
||||||
|
|
||||||
var source = new SSE('/site_files/chat', {payload: formData, debug: false});
|
var source = new SSE('/site_files/chat', {payload: formData, debug: false});
|
||||||
|
|
||||||
|
@ -46,6 +74,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
messageElement.innerHTML = DOMPurify.sanitize(marked.parse(accumulatingMessage));
|
messageElement.innerHTML = DOMPurify.sanitize(marked.parse(accumulatingMessage));
|
||||||
messageElement.querySelectorAll('code').forEach((block) => {
|
messageElement.querySelectorAll('code').forEach((block) => {
|
||||||
hljs.highlightElement(block);
|
hljs.highlightElement(block);
|
||||||
|
addCopyButton(messageElement)
|
||||||
});
|
});
|
||||||
|
|
||||||
scrollToBottom();
|
scrollToBottom();
|
||||||
|
@ -53,8 +82,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
|
||||||
source.addEventListener('content_block_stop', function(e) {
|
source.addEventListener('content_block_stop', function(e) {
|
||||||
var payload = JSON.parse(e.data);
|
var payload = JSON.parse(e.data);
|
||||||
const messageElement = chatBox.lastElementChild;
|
messages.push({role: 'assistant', content: accumulatingMessage})
|
||||||
// console.log(accumulatingMessage);
|
|
||||||
accumulatingMessage = '';
|
accumulatingMessage = '';
|
||||||
chatForm.querySelector('button').disabled = false;
|
chatForm.querySelector('button').disabled = false;
|
||||||
});
|
});
|
||||||
|
@ -79,4 +107,29 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
const observer = new MutationObserver(scrollToBottom);
|
const observer = new MutationObserver(scrollToBottom);
|
||||||
observer.observe(chatBox, { childList: true });
|
observer.observe(chatBox, { childList: true });
|
||||||
|
|
||||||
|
|
||||||
|
// Copy button
|
||||||
|
|
||||||
|
function addCopyButton(parentElement) {
|
||||||
|
const codeBoxes = parentElement.querySelectorAll('pre code');
|
||||||
|
|
||||||
|
codeBoxes.forEach(codeBox => {
|
||||||
|
const copyButton = document.createElement('button');
|
||||||
|
copyButton.innerText = 'Copy';
|
||||||
|
copyButton.classList.add('copy-button');
|
||||||
|
|
||||||
|
copyButton.addEventListener('click', () => {
|
||||||
|
const code = codeBox.innerText;
|
||||||
|
navigator.clipboard.writeText(code);
|
||||||
|
copyButton.innerText = 'Copied!';
|
||||||
|
setTimeout(() => {
|
||||||
|
copyButton.innerText = 'Copy';
|
||||||
|
}, 2000);
|
||||||
|
});
|
||||||
|
|
||||||
|
codeBox.parentElement.style.position = 'relative';
|
||||||
|
codeBox.parentElement.appendChild(copyButton);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
|
@ -2287,14 +2287,13 @@ pre, code {
|
||||||
background-color: #121212;
|
background-color: #121212;
|
||||||
color: #e0e0e0;
|
color: #e0e0e0;
|
||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
border: 1px solid #333; /* Optional: adds a slight border for visual structure */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-box {
|
.chat-box {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background-color: #1e1e1e;
|
background-color: #1d1f21;
|
||||||
|
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-size: 13.5px;
|
font-size: 13.5px;
|
||||||
|
@ -2328,7 +2327,7 @@ pre, code {
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-message {
|
.user-message {
|
||||||
text-align: right;
|
text-align: left;
|
||||||
background-color: #5e95a1;
|
background-color: #5e95a1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2358,8 +2357,23 @@ pre, code {
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.copy-button {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
background-color: #acd473;
|
||||||
|
padding: 5px 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-button:hover {
|
||||||
|
background-color: #45a049;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.chat-container {
|
.chat-container {
|
||||||
form {
|
form {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -114,7 +114,12 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-33" style="flex: 33%; padding: 10px">
|
<div class="col col-33" style="flex: 33%; padding: 10px">
|
||||||
<div class="chat-container">
|
<div class="chat-container">
|
||||||
<div id="chat-box" class="chat-box"></div>
|
<div id="chat-box" class="chat-box">
|
||||||
|
<div class="bot-message message">
|
||||||
|
<p>I'm Penelope, your coding assistant! I'm here to answer any questions you have about coding web sites. I'm quite good at coding, but can be incorrect on general knowledge, so be sure to verify facts.</p>
|
||||||
|
<p>How can I help you today?</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<form id="chat-form">
|
<form id="chat-form">
|
||||||
<input name="csrf_token" value="<%= csrf_token %>" type="hidden">
|
<input name="csrf_token" value="<%= csrf_token %>" type="hidden">
|
||||||
<input type="text" id="chat-input" placeholder="Ask a coding question..." value="give me a hello world html file" autocomplete="off">
|
<input type="text" id="chat-input" placeholder="Ask a coding question..." value="give me a hello world html file" autocomplete="off">
|
||||||
|
|
Loading…
Add table
Reference in a new issue