-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchatbot.js
More file actions
155 lines (134 loc) · 4.41 KB
/
chatbot.js
File metadata and controls
155 lines (134 loc) · 4.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
const chatbox = document.getElementById("chatbox");
const form = document.getElementById("chat-form");
const input = document.getElementById("chat-input");
const chatContainer = document.getElementById("plumber-chat");
const chatLauncher = document.getElementById("chat-launcher");
// Determine the Ollama API host dynamically
const ollamaHost = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1'
? 'http://localhost:11434'
: `http://${window.location.hostname}:11434`;
console.log('ollamaHost:', ollamaHost);
// Add message to chat
function addMessage(msg, sender = "bot") {
const div = document.createElement("div");
div.className = sender;
div.innerHTML = msg;
chatbox.appendChild(div);
chatbox.scrollTop = chatbox.scrollHeight;
return div; // Return the div so we can modify it later
}
// Function to send message to Ollama API and handle streaming response
async function sendToOllama(message) {
try {
// Create a bot message element that we'll update
const botMessage = addMessage("...", "bot");
let fullResponse = '';
const response = await fetch('/api/ollama', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'tinyllama',
messages: [{ role: 'user', content: message }],
stream: true,
options: {
num_predict: 42, // Limits response to ~42 tokens
temperature: 0.7, // Controls randomness (0-1, lower is more deterministic)
}
}),
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
const lines = chunk.split('\n').filter(line => line.trim() !== '');
for (const line of lines) {
try {
const data = JSON.parse(line);
if (data.message?.content) {
fullResponse += data.message.content;
// Update the bot message in real-time
botMessage.innerHTML = fullResponse;
chatbox.scrollTop = chatbox.scrollHeight;
}
} catch (e) {
console.error('Error parsing JSON chunk:', e);
}
}
}
return fullResponse;
} catch (error) {
console.error('Error communicating with Ollama:', error);
return "Oops, something went wrong. Please try again later.";
}
}
// Handle form submission
form.addEventListener("submit", async function (e) {
e.preventDefault();
const userText = input.value.trim();
if (userText === "") return;
// Display user message
addMessage(userText, "user");
input.value = "";
// Get response from Ollama (will stream automatically)
await sendToOllama(userText);
});
// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // //
// State Variable
let stage = 0;
const goTopBtn = document.querySelector('.go-top');
// Chat show/hide toggle
function toggleChat() {
const isOpen = chatContainer.classList.contains('visible');
if (isOpen) {
// Hide chat
chatContainer.classList.remove('visible');
setTimeout(() => {
chatContainer.style.display = 'none';
chatLauncher.classList.remove('hidden');
goTopBtn.classList.add('show'); // show go to top button
}, 300);
} else {
// Show chat
chatContainer.style.display = 'flex';
setTimeout(() => {
chatContainer.classList.add('visible');
goTopBtn.classList.remove('show'); // hide go to top button
}, 10);
chatLauncher.classList.add('hidden');
// Initial message
if (stage === 0) {
setTimeout(() => {
addMessage("👋 Hello! I'm PlumberBot. Say hi to get started!");
stage += 1;
}, 1000);
}
}
}
// customer info variable
let userData = {
name: "",
issue: "",
phone: "",
email: "",
postcode: "",
timestamp_frontend: "",
timestamp_backend: "",
};
// Save Lead with customer info
function sendLeadToServer() {
fetch('/send-lead', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(userData)
})
.then(res => res.text())
.then(msg => console.log(msg))
.catch(err => console.error("Error sending lead:", err));
}