about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--html/matt-chat/index.html180
1 files changed, 149 insertions, 31 deletions
diff --git a/html/matt-chat/index.html b/html/matt-chat/index.html
index 2d93dfc..5747438 100644
--- a/html/matt-chat/index.html
+++ b/html/matt-chat/index.html
@@ -84,13 +84,14 @@
             background-color: #007BFF;
             color: white;
             text-align: right;
-            margin-right: 20px;
+            margin-left: 20px;
         }
 
         .bot-message {
             background-color: #f0f0f0;
             color: #333;
-            margin-left: 20px;
+            text-align: left;
+            margin-right: 20px;
         }
 
         @media (max-width: 600px) {
@@ -184,11 +185,18 @@
                 { value: "qwen2.5-coder:1.5b", label: "qwen2.5-coder:1.5b, fast coding" },
                 { value: "qwen2.5-coder:7b", label: "qwen2.5-coder:7b, fast-ish coding" }
             ],
-            contextWindowSize: 3, // Number of previous exchanges to remember
-            systemMessage: "You are a helpful assistant. If you don't know something you'll let me know. Your name is Matt." // Set the mood and personality for the LLM's responses
+            contextWindowSize: 6, // Number of previous exchanges to remember
+            systemMessage: "You are a helpful assistant. If you don't know something you'll let me know. Your name is Matt.", // Set the mood and personality for the LLM's responses
+            maxTokens: 4096, // Approximate max tokens for most models
+            summarizeThreshold: 3584, // When to trigger summarization
+        };
+
+        let conversationHistory = {
+            summary: null,
+            current: [],
+            full: []
         };
 
-        let conversationHistory = [];
         let isCatMode = false; // Flag to track cat mode
 
         function populateModelSelect() {
@@ -306,10 +314,15 @@
                 return;
             }
 
-            addMessage(userMessage, "user");
-            conversationHistory.push({ role: "user", content: userMessage }); // Add user message to history
-            userInput.value = "";
+            if (userMessage.toLowerCase() === '/context') {
+                const context = viewCurrentContext();
+                addMessage(`Current conversation has ${context.currentMessages} messages\nEstimated tokens: ${context.estimatedTokens}`, "bot");
+                return;
+            }
 
+            addMessage(userMessage, "user");
+            userInput.value = ""; // Add this line back to clear the input
+            
             // Reset the counter
             document.getElementById("char-count").textContent = "0";
             document.getElementById("word-count").textContent = "0";
@@ -332,15 +345,7 @@
                 const retainHistory = document.getElementById("retain-history").checked; // Check the checkbox state
 
                 // Prepare the messages for the API
-                const messagesToSend = [
-                    { role: "system", content: config.systemMessage },
-                    { role: "user", content: userMessage }
-                ];
-
-                // Include conversation history only if the checkbox is checked
-                if (retainHistory) {
-                    messagesToSend.push(...conversationHistory.slice(-config.contextWindowSize * 2)); // Get the last few exchanges
-                }
+                const messagesToSend = await prepareMessages(userMessage);
 
                 const response = await fetch(config.apiUrl, {
                     method: "POST",
@@ -362,25 +367,22 @@
 
                 if (data.choices && data.choices.length > 0) {
                     const botResponse = data.choices[0].message.content;
-
-                    // Calculate the duration
-                    const duration = Date.now() - startTime; // Time taken in milliseconds
-
+                    
                     // Clear loading indicator
                     clearInterval(animationInterval);
                     loadingIndicator.remove();
-
-                    // Add bot's response to chat
+                    
+                    // Add bot's response to chat and history
                     addMessage(botResponse, "bot");
-                    conversationHistory.push({ role: "bot", content: botResponse }); // Add bot response to history
+                    conversationHistory.current.push({ role: "assistant", content: botResponse });
 
-                    // Display the time taken
+                    // Calculate and display duration
+                    const duration = Date.now() - startTime;
                     const timeTakenMessage = formatDuration(duration);
                     const timeDisplay = document.createElement("div");
                     timeDisplay.classList.add("bot-time");
                     timeDisplay.textContent = `Response time: ${timeTakenMessage}`;
-                    timeDisplay.style.textAlign = "center"; // Center the text
-                    document.getElementById("chat-container").appendChild(timeDisplay); // Append the time display
+                    document.getElementById("chat-container").appendChild(timeDisplay);
                 } else {
                     console.error("No response from API");
                     loadingIndicator.remove();
@@ -388,8 +390,8 @@
                 }
 
                 // Optional: Limit the conversation history to the last 10 messages
-                if (conversationHistory.length > 10) {
-                    conversationHistory.shift(); // Remove the oldest message
+                if (conversationHistory.current.length > 10) {
+                    conversationHistory.current.shift(); // Remove the oldest message
                 }
 
             } catch (error) {
@@ -454,8 +456,12 @@
 
         function clearChat() {
             const chatContainer = document.getElementById("chat-container");
-            chatContainer.innerHTML = ""; // Clear all messages
-            conversationHistory = []; // Clear the conversation history
+            chatContainer.innerHTML = "";
+            conversationHistory = {
+                summary: null,
+                current: [],
+                full: []
+            };
         }
 
         function displayHelp() {
@@ -468,6 +474,118 @@
             `;
             addMessage(helpMessage, "bot"); // Display help message as a bot message
         }
+
+        function estimateTokens(text) {
+            // Rough estimation: ~4 chars per token for English text
+            return Math.ceil(text.length / 4);
+        }
+
+        function getContextSize(messages) {
+            return messages.reduce((sum, msg) => sum + estimateTokens(msg.content), 0);
+        }
+
+        async function summarizeConversation(messages) {
+            try {
+                const modelSelect = document.getElementById("model-select");
+                const selectedModel = modelSelect.value;
+
+                const response = await fetch(config.apiUrl, {
+                    method: "POST",
+                    headers: {
+                        "Content-Type": "application/json",
+                    },
+                    body: JSON.stringify({
+                        model: selectedModel,
+                        messages: messages,
+                    }),
+                });
+
+                const data = await response.json();
+                return data.choices[0].message.content;
+            } catch (error) {
+                console.error("Error summarizing conversation:", error);
+                return null;
+            }
+        }
+
+        async function prepareMessages(userMessage) {
+            const messages = [];
+            
+            // Always start with system message
+            messages.push({ role: "system", content: config.systemMessage });
+            
+            if (document.getElementById("retain-history").checked) {
+                // If we have a summary, add it more naturally
+                if (conversationHistory.summary) {
+                    messages.push({
+                        role: "system",
+                        content: `Previous discussion: ${conversationHistory.summary}`
+                    });
+                }
+                
+                // Add current conversation segment
+                messages.push(...conversationHistory.current);
+            }
+            
+            // We'll add the new message to history here, before we check for summarization
+            const newMessage = { role: "user", content: userMessage };
+            conversationHistory.current.push(newMessage);
+            messages.push(newMessage);
+            
+            // Check if we need to summarize
+            const totalTokens = getContextSize(messages);
+            if (totalTokens > config.summarizeThreshold) {
+                // Move current messages to full history, except for the newest message
+                conversationHistory.full.push(...conversationHistory.current.slice(0, -1));
+                
+                // Create a more natural summarization prompt
+                const summary = await summarizeConversation([
+                    {
+                        role: "system",
+                        content: "Summarize this conversation's key points and context that would be important for continuing the discussion naturally. Be concise but maintain essential details."
+                    },
+                    ...conversationHistory.full
+                ]);
+                
+                if (summary) {
+                    conversationHistory.summary = summary;
+                    // Keep only the most recent messages for immediate context
+                    conversationHistory.current = conversationHistory.current.slice(-4);
+                    
+                    // Rebuild messages array with new summary
+                    return [
+                        { role: "system", content: config.systemMessage },
+                        { role: "system", content: `Previous discussion: ${summary}` },
+                        ...conversationHistory.current
+                    ];
+                }
+            }
+            
+            return messages;
+        }
+
+        // Add a function to clean up old messages periodically
+        function pruneConversationHistory() {
+            if (conversationHistory.full.length > 100) {
+                // Keep only the last 100 messages in full history
+                conversationHistory.full = conversationHistory.full.slice(-100);
+            }
+        }
+
+        // Call this after successful responses
+        setInterval(pruneConversationHistory, 60000); // Clean up every minute
+
+        // Add these functions to help debug and manage context
+        function viewCurrentContext() {
+            const context = {
+                summary: conversationHistory.summary,
+                currentMessages: conversationHistory.current.length,
+                fullHistoryMessages: conversationHistory.full.length,
+                estimatedTokens: getContextSize(conversationHistory.current)
+            };
+            console.log("Current Context:", context);
+            return context;
+        }
     </script>
 </body>
 </html>