diff --git a/.aider.conf.yml b/.aider.conf.yml
index 8619221..aa77361 100644
--- a/.aider.conf.yml
+++ b/.aider.conf.yml
@@ -1 +1 @@
-model: ollama_chat/qwen2.5-coder:14b-instruct-q4_K_M
\ No newline at end of file
+model: /models/Qwen/Qwen2.5-Coder-32B-Instruct-GGUF/qwen2.5-coder-32b-instruct-q4_k_m.gguf
\ No newline at end of file
diff --git a/.aider.model.settings.yml b/.aider.model.settings.yml
index 43facbf..0e3af4d 100644
--- a/.aider.model.settings.yml
+++ b/.aider.model.settings.yml
@@ -1,3 +1,4 @@
-- name: /models/qwen2.5-coder-32b-instruct-q4_k_m.gguf
+- name: /models/Qwen/Qwen2.5-Coder-32B-Instruct-GGUF/qwen2.5-coder-32b-instruct-q4_k_m.gguf
extra_params:
- num_ctx: 16384
\ No newline at end of file
+ num_ctx: 16384
+ num_threads: 8
\ No newline at end of file
diff --git a/.aiignore b/.aiignore
index 62c8935..a3a7798 100644
--- a/.aiignore
+++ b/.aiignore
@@ -1 +1,5 @@
-.idea/
\ No newline at end of file
+.idea/
+.aider.tags.cache.v4
+.aider.chat.history.md
+.aider.input.history
+.env
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..40816a2
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+Hi
\ No newline at end of file
diff --git a/chat.js b/chatv2.js
similarity index 85%
rename from chat.js
rename to chatv2.js
index 76e5927..be84359 100644
--- a/chat.js
+++ b/chatv2.js
@@ -2,23 +2,24 @@
const BACKENDS = {
plato : {
prod: '/api/plato',
- dev : 'http://192.168.1.74:1234/v1',
+ dev : 'http://192.168.1.74:1234/v1', // Removed trailing space
name: 'Plato (192.168.1.74)'
},
stoic : {
prod: '/api/stoic',
- dev : 'http://192.168.1.159:1234/v1',
+ dev : 'http://192.168.1.159:1234/v1', // Removed trailing space
name: 'Stoic (192.168.1.159)'
},
ollama: {
prod: '/api/ollama',
- dev : 'http://192.168.1.159:8081/v1',
+ dev : 'http://192.168.1.159:8081/v1', // Removed trailing space
name: 'Ollama (192.168.1.159:8081)'
}
}
const IS_PRODUCTION = window.location.hostname === 'jarvis-lan.appmodel.nl'
const API_KEY = 'not-needed'
+const MAX_CHAT_HISTORY = 50 // Maximum messages to keep in history
// Global state
let currentBackend = 'plato'
@@ -26,7 +27,7 @@ let currentModel = null
let availableModels = []
let currentStreamController = null
let isStreaming = false
-let chatHistory = [] // Initialize chat history array
+let chatHistory = [] // Stores conversation history
// Get current API URL based on selected backend
function getApiUrl() {
@@ -38,7 +39,7 @@ function getApiUrl() {
function updateBackendDisplay() {
const backend = BACKENDS[currentBackend]
const displayText = IS_PRODUCTION
- ? `${ backend.prod } → ${ backend.name }`
+ ? `${ backend.prod } ? ${ backend.name }`
: backend.dev
document.getElementById('backendDisplay').textContent = displayText
}
@@ -84,6 +85,23 @@ function populateModelSelector() {
}
}
+// Get formatted messages for API (excludes UI-specific properties)
+function getApiMessages() {
+ // Get last N messages and format for API
+ return chatHistory.slice(-MAX_CHAT_HISTORY).map(({ role, content }) => ({
+ role,
+ content
+ }))
+}
+
+// Trim chat history if it exceeds maximum
+function trimChatHistory() {
+ if (chatHistory.length > MAX_CHAT_HISTORY) {
+ chatHistory = chatHistory.slice(-MAX_CHAT_HISTORY)
+ console.log(`Chat history trimmed to ${ MAX_CHAT_HISTORY } messages`)
+ }
+}
+
// Handle backend and model selection changes
document.addEventListener('DOMContentLoaded', () => {
const backendSelector = document.getElementById('backendSelector')
@@ -96,7 +114,7 @@ document.addEventListener('DOMContentLoaded', () => {
backendSelector.addEventListener('change', (e) => {
currentBackend = e.target.value
updateBackendDisplay()
- console.log('Backend switched to:', currentBackend, '→', getApiUrl())
+ console.log('Backend switched to:', currentBackend, '?', getApiUrl())
fetchModels() // Reload models for new backend
})
@@ -146,7 +164,7 @@ function addMessage(role, content, markdown = false, messageId = null) {
const avatar = document.createElement('div')
avatar.className = `avatar ${ role }-avatar`
- avatar.textContent = role === 'user' ? '👤' : '🤖'
+ avatar.textContent = role === 'user' ? '?' : '?'
const name = document.createElement('span')
name.textContent = role === 'user' ? 'You' : 'Assistant'
@@ -183,9 +201,12 @@ function addMessage(role, content, markdown = false, messageId = null) {
chatLog.appendChild(messageDiv)
chatLog.scrollTop = chatLog.scrollHeight
- // Add message to chat history
+ // Store message in history (excluding UI-specific properties)
chatHistory.push({ role, content, markdown, messageId })
+ // Trim history if it gets too long
+ trimChatHistory()
+
return contentDiv
}
@@ -201,8 +222,8 @@ function parseThinkingTags(content) {
const id = `thinking-${ Date.now() }-${ thinkingCounter }`
return `
`
@@ -215,8 +236,8 @@ function parseThinkingTags(content) {
const id = `thinking-${ Date.now() }-${ thinkingCounter }`
return ``
@@ -267,7 +288,7 @@ function showTypingIndicator() {
const avatar = document.createElement('div')
avatar.className = 'avatar assistant-avatar'
- avatar.textContent = '🤖'
+ avatar.textContent = '?'
const name = document.createElement('span')
name.textContent = 'Assistant'
@@ -315,7 +336,7 @@ async function handleStreamingResponse(userMessage) {
const avatar = document.createElement('div')
avatar.className = 'avatar assistant-avatar'
- avatar.textContent = '🤖'
+ avatar.textContent = '?'
const name = document.createElement('span')
name.textContent = 'Assistant'
@@ -344,7 +365,7 @@ async function handleStreamingResponse(userMessage) {
const requestBody = {
model : currentModel || 'local-model',
- messages : [{ role: 'user', content: userMessage }],
+ messages : getApiMessages(), // Send full chat history
stream : true,
temperature: 0.7,
max_tokens : 2000
@@ -384,7 +405,7 @@ async function handleStreamingResponse(userMessage) {
// Update immediately if enough time has passed
updateScheduled = true
requestAnimationFrame(() => {
- updateMessageContent(contentDiv, accumulatedContent, markdownToggle.checked)
+ updateMessageContent(contentDiv, accumulatedContent, markdownToggle.checked, 'assistant')
if (cursorSpan.parentNode) {
contentDiv.appendChild(cursorSpan)
}
@@ -397,7 +418,7 @@ async function handleStreamingResponse(userMessage) {
updateScheduled = true
setTimeout(() => {
requestAnimationFrame(() => {
- updateMessageContent(contentDiv, accumulatedContent, markdownToggle.checked)
+ updateMessageContent(contentDiv, accumulatedContent, markdownToggle.checked, 'assistant')
if (cursorSpan.parentNode) {
contentDiv.appendChild(cursorSpan)
}
@@ -424,7 +445,7 @@ async function handleStreamingResponse(userMessage) {
isStreaming = false
currentStreamController = null
// Final update and remove cursor
- updateMessageContent(contentDiv, accumulatedContent, markdownToggle.checked)
+ updateMessageContent(contentDiv, accumulatedContent, markdownToggle.checked, 'assistant')
if (cursorSpan.parentNode) {
cursorSpan.parentNode.removeChild(cursorSpan)
}
@@ -446,19 +467,18 @@ async function handleStreamingResponse(userMessage) {
}
// Final update
- updateMessageContent(contentDiv, accumulatedContent, markdownToggle.checked)
+ updateMessageContent(contentDiv, accumulatedContent, markdownToggle.checked, 'assistant')
chatLog.scrollTop = chatLog.scrollHeight
} catch (error) {
console.error('Streaming error:', error)
if (error.name !== 'AbortError') {
- updateMessageContent(contentDiv, `Error: ${ error.message }`, false)
+ updateMessageContent(contentDiv, `Error: ${ error.message }`, false, 'assistant')
}
} finally {
isStreaming = false
currentStreamController = null
sendBtn.disabled = false
- userInput.focus()
// Remove cursor if still exists
if (cursorSpan.parentNode) {
@@ -480,7 +500,7 @@ async function handleNonStreamingResponse(userMessage) {
const requestBody = {
model : currentModel || 'local-model',
- messages : [{ role: 'user', content: userMessage }],
+ messages : getApiMessages(), // Send full chat history
stream : false,
temperature: 0.7,
max_tokens : 2000
@@ -519,12 +539,6 @@ async function handleNonStreamingResponse(userMessage) {
}
}
-function loadChatHistory() {
- chatHistory.forEach(message => {
- addMessage(message.role, message.content, message.markdown, message.messageId)
- })
-}
-
// Stop current stream
function stopStream() {
if (currentStreamController) {
@@ -541,17 +555,24 @@ async function sendMessage() {
const userMessage = userInput.value.trim()
if (!userMessage || isStreaming) return
+ // Add user message to UI and history
addMessage('user', userMessage)
+
+ // Clear input field
userInput.value = ''
userInput.style.height = 'auto'
sendBtn.disabled = true
+ // Update button text based on streaming state
if (streamToggle.checked) {
sendBtn.textContent = 'Stop'
- handleStreamingResponse(userMessage)
+ await handleStreamingResponse(userMessage)
} else {
- handleNonStreamingResponse(userMessage)
+ await handleNonStreamingResponse(userMessage)
}
+
+ // Reset button text
+ sendBtn.textContent = 'Send'
}
// Event Listeners
@@ -577,28 +598,25 @@ window.onload = () => {
userInput.focus()
fetchModels()
- // Load chat history
- loadChatHistory()
+ // Add welcome message (this will be the first entry in chatHistory)
+ const welcomeMessage = `# Welcome to LM Studio Chat! ?
- // Add welcome message
- setTimeout(() => {
- const welcomeMessage = `# Welcome to LM Studio Chat! 🚀
-
-I now support **real-time streaming responses** and **dark, readable text formatting**.
+I now support **full conversation history**, **real-time streaming responses** and **dark, readable text formatting**.
## Features:
-1. **Streaming Mode** (enabled by default) - Watch responses appear word-by-word
-2. **Markdown Rendering** - Proper formatting for code, lists, tables, and more
-3. **Readable Dark Text** - No more eye strain from light gray text
-4. **Model Detection** - Automatically shows your loaded model
+1. **Full Chat History** - Complete conversation context is now sent to the AI
+2. **Smart History Management** - Automatically keeps the last ${ MAX_CHAT_HISTORY } messages
+3. **Streaming Mode** (enabled by default) - Watch responses appear word-by-word
+4. **Markdown Rendering** - Proper formatting for code, lists, tables, and more
+5. **Readable Dark Text** - No more eye strain from light gray text
## Try it out:
-- Ask a technical question to see **code formatting**
-- Type \`ls -la\` in a code block
-- Request a **numbered list** or table
+- Ask follow-up questions that reference earlier messages
+- Have a multi-turn conversation with full context
+- Ask "what did I just ask?" to test history retention
- Watch the streaming response in real-time!
> *Tip: You can toggle streaming and markdown using the checkboxes below.*`
- addMessage('assistant', welcomeMessage, true)
- }, 500)
-}
+
+ addMessage('assistant', welcomeMessage, true)
+}
\ No newline at end of file
diff --git a/index.html b/index.html
index 72850e2..9034621 100644
--- a/index.html
+++ b/index.html
@@ -58,612 +58,6 @@
-
+