From 4bd2390c1dccd335269f691c3e43fcfd7e2f9561 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Mon, 25 Mar 2024 17:40:28 -0500 Subject: [PATCH] chat: multi-message prompting, system message, copy button, temp setting --- app/site_files.rb | 4 +- public/js/chat.js | 63 ++++++++++++++++++++++++--- sass/_project-sass/_project-Main.scss | 20 +++++++-- views/site_files/text_editor.erb | 7 ++- 4 files changed, 84 insertions(+), 10 deletions(-) diff --git a/app/site_files.rb b/app/site_files.rb index 80ff326a..a5b0086c 100644 --- a/app/site_files.rb +++ b/app/site_files.rb @@ -245,8 +245,10 @@ post '/site_files/chat' do body = { model: "claude-3-haiku-20240307", - messages: [{role: "user", content: params[:message]}], + system: params[:system], + messages: JSON.parse(params[:messages]), max_tokens: 4096, + temperature: 0.5, stream: true }.to_json diff --git a/public/js/chat.js b/public/js/chat.js index 0061ec04..b8380131 100644 --- a/public/js/chat.js +++ b/public/js/chat.js @@ -1,11 +1,37 @@ document.addEventListener('DOMContentLoaded', () => { - console.log('fart') const chatForm = document.getElementById('chat-form'); const chatBox = document.getElementById('chat-box'); const chatInput = document.getElementById('chat-input'); + let messages = []; 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) { + event.preventDefault(); const message = chatInput.value.trim(); @@ -16,17 +42,19 @@ document.addEventListener('DOMContentLoaded', () => { chatForm.querySelector('button').disabled = true; addMessage('user'); + messages.push({role: 'user', content: message}) chatBox.lastElementChild.innerHTML = DOMPurify.sanitize(message); const highlightedCode = hljs.highlight(message, { language: 'plaintext' }).value - console.log(highlightedCode) chatBox.lastElementChild.innerHTML = DOMPurify.sanitize(highlightedCode); chatInput.value = ''; var formData = new FormData(); 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}); @@ -46,6 +74,7 @@ document.addEventListener('DOMContentLoaded', () => { messageElement.innerHTML = DOMPurify.sanitize(marked.parse(accumulatingMessage)); messageElement.querySelectorAll('code').forEach((block) => { hljs.highlightElement(block); + addCopyButton(messageElement) }); scrollToBottom(); @@ -53,8 +82,7 @@ document.addEventListener('DOMContentLoaded', () => { source.addEventListener('content_block_stop', function(e) { var payload = JSON.parse(e.data); - const messageElement = chatBox.lastElementChild; - // console.log(accumulatingMessage); + messages.push({role: 'assistant', content: accumulatingMessage}) accumulatingMessage = ''; chatForm.querySelector('button').disabled = false; }); @@ -79,4 +107,29 @@ document.addEventListener('DOMContentLoaded', () => { const observer = new MutationObserver(scrollToBottom); 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); + }); + } + }); \ No newline at end of file diff --git a/sass/_project-sass/_project-Main.scss b/sass/_project-sass/_project-Main.scss index 062a2e65..b029fae7 100644 --- a/sass/_project-sass/_project-Main.scss +++ b/sass/_project-sass/_project-Main.scss @@ -2287,14 +2287,13 @@ pre, code { background-color: #121212; color: #e0e0e0; font-family: Arial, sans-serif; - border: 1px solid #333; /* Optional: adds a slight border for visual structure */ } .chat-box { flex-grow: 1; overflow-y: auto; padding: 10px; - background-color: #1e1e1e; + background-color: #1d1f21; font-weight: 300; font-size: 13.5px; @@ -2328,7 +2327,7 @@ pre, code { } .user-message { - text-align: right; + text-align: left; background-color: #5e95a1; } @@ -2358,8 +2357,23 @@ pre, code { word-wrap: break-word; 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 { form { display: flex; diff --git a/views/site_files/text_editor.erb b/views/site_files/text_editor.erb index d8057044..d120a48d 100644 --- a/views/site_files/text_editor.erb +++ b/views/site_files/text_editor.erb @@ -114,7 +114,12 @@
-
+
+
+

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.

+

How can I help you today?

+
+