mhndayesh commited on
Commit
d14e935
·
verified ·
1 Parent(s): b144a65

Update app.js

Browse files
Files changed (1) hide show
  1. app.js +135 -134
app.js CHANGED
@@ -1,134 +1,135 @@
1
- // --- CONFIGURATION ---
2
- // Set this to your Railway URL (e.g., "https://your-app.up.railway.app")
3
- // Leave as empty string "" if the frontend and backend are on the same server.
4
- const BACKEND_URL = "";
5
-
6
- const chatContainer = document.getElementById('chat-container');
7
- const userInput = document.getElementById('user-input');
8
- const sendBtn = document.getElementById('send-btn');
9
- const statsDisplay = document.getElementById('pipeline-stats');
10
-
11
- // BYOK Elements
12
- const settingsToggle = document.getElementById('settings-toggle');
13
- const settingsPanel = document.getElementById('settings-panel');
14
- const apiKeyInput = document.getElementById('api-key-input');
15
- const llmModelInput = document.getElementById('llm-model-input');
16
- const embedModelInput = document.getElementById('embed-model-input');
17
-
18
- // Load saved settings from localStorage
19
- apiKeyInput.value = localStorage.getItem('byok_api_key') || '';
20
- llmModelInput.value = localStorage.getItem('byok_llm_model') || 'openai/gpt-4o-mini';
21
- embedModelInput.value = localStorage.getItem('byok_embed_model') || 'qwen/qwen3-embedding-8b';
22
-
23
- // Toggle Settings Panel
24
- settingsToggle.addEventListener('click', () => {
25
- settingsPanel.classList.toggle('active');
26
- });
27
-
28
- /**
29
- * Adds a message bubble to the chat container
30
- */
31
- function addMessage(text, role) {
32
- // Remove welcome message if it exists
33
- const welcome = document.querySelector('.welcome-message');
34
- if (welcome) welcome.remove();
35
-
36
- const msgDiv = document.createElement('div');
37
- msgDiv.classList.add('message', `${role}-message`);
38
- msgDiv.textContent = text;
39
- chatContainer.appendChild(msgDiv);
40
- chatContainer.scrollTop = chatContainer.scrollHeight;
41
- return msgDiv;
42
- }
43
-
44
- /**
45
- * Adds a visual typing indicator
46
- */
47
- function addLoadingIndicator() {
48
- const loader = document.createElement('div');
49
- loader.classList.add('message', 'bot-message', 'loading-msg');
50
- loader.innerHTML = `
51
- <div class="typing-indicator">
52
- <span></span><span></span><span></span>
53
- </div>
54
- `;
55
- chatContainer.appendChild(loader);
56
- chatContainer.scrollTop = chatContainer.scrollHeight;
57
- return loader;
58
- }
59
-
60
- /**
61
- * Main function to send message and get BYOK response
62
- */
63
- async function sendMessage() {
64
- const text = userInput.value.trim();
65
- if (!text) return;
66
-
67
- // Persist settings to localStorage
68
- localStorage.setItem('byok_api_key', apiKeyInput.value);
69
- localStorage.setItem('byok_llm_model', llmModelInput.value);
70
- localStorage.setItem('byok_embed_model', embedModelInput.value);
71
-
72
- // Clear input and add user message
73
- userInput.value = '';
74
- userInput.style.height = 'auto';
75
- addMessage(text, 'user');
76
-
77
- // Add loading indicator
78
- const loader = addLoadingIndicator();
79
-
80
- try {
81
- const response = await fetch(`${BACKEND_URL}/chat`, {
82
- method: 'POST',
83
- headers: { 'Content-Type': 'application/json' },
84
- body: JSON.stringify({
85
- message: text,
86
- api_key: apiKeyInput.value || null,
87
- llm_model: llmModelInput.value || null,
88
- embed_model: embedModelInput.value || null
89
- })
90
- });
91
-
92
- const data = await response.json();
93
-
94
- // Remove loader and add bot response
95
- loader.remove();
96
- if (data.answer) {
97
- addMessage(data.answer, 'bot');
98
-
99
- // Update performance stats
100
- const pipeTime = data.total_time ? data.total_time.toFixed(1) : '--';
101
- const retTime = data.timings && data.timings.retrieval ? data.timings.retrieval.toFixed(2) : '--';
102
- statsDisplay.textContent = `Pipeline: ${pipeTime}s | Retrieval: ${retTime}s`;
103
- } else {
104
- addMessage('Error: No response from engine.', 'bot');
105
- }
106
- } catch (err) {
107
- if (loader) loader.remove();
108
- addMessage(`Error: ${err.message}`, 'bot');
109
- }
110
- }
111
-
112
- /**
113
- * Helper for suggestion buttons
114
- */
115
- function useSuggestion(text) {
116
- userInput.value = text;
117
- sendMessage();
118
- }
119
-
120
- // Event Listeners
121
- sendBtn.addEventListener('click', sendMessage);
122
-
123
- userInput.addEventListener('keydown', (e) => {
124
- if (e.key === 'Enter' && !e.shiftKey) {
125
- e.preventDefault();
126
- sendMessage();
127
- }
128
- });
129
-
130
- // Auto-resize textarea as user types
131
- userInput.addEventListener('input', function () {
132
- this.style.height = 'auto';
133
- this.style.height = (this.scrollHeight) + 'px';
134
- });
 
 
1
+ // --- CONFIGURATION ---
2
+ // Set this to your Railway URL (e.g., "https://your-app.up.railway.app")
3
+ // Leave as empty string "" if the frontend and backend are on the same server.
4
+ const BACKEND_URL = "https://your-railway-app.up.railway.app";
5
+
6
+
7
+ const chatContainer = document.getElementById('chat-container');
8
+ const userInput = document.getElementById('user-input');
9
+ const sendBtn = document.getElementById('send-btn');
10
+ const statsDisplay = document.getElementById('pipeline-stats');
11
+
12
+ // BYOK Elements
13
+ const settingsToggle = document.getElementById('settings-toggle');
14
+ const settingsPanel = document.getElementById('settings-panel');
15
+ const apiKeyInput = document.getElementById('api-key-input');
16
+ const llmModelInput = document.getElementById('llm-model-input');
17
+ const embedModelInput = document.getElementById('embed-model-input');
18
+
19
+ // Load saved settings from localStorage
20
+ apiKeyInput.value = localStorage.getItem('byok_api_key') || '';
21
+ llmModelInput.value = localStorage.getItem('byok_llm_model') || 'openai/gpt-4o-mini';
22
+ embedModelInput.value = localStorage.getItem('byok_embed_model') || 'qwen/qwen3-embedding-8b';
23
+
24
+ // Toggle Settings Panel
25
+ settingsToggle.addEventListener('click', () => {
26
+ settingsPanel.classList.toggle('active');
27
+ });
28
+
29
+ /**
30
+ * Adds a message bubble to the chat container
31
+ */
32
+ function addMessage(text, role) {
33
+ // Remove welcome message if it exists
34
+ const welcome = document.querySelector('.welcome-message');
35
+ if (welcome) welcome.remove();
36
+
37
+ const msgDiv = document.createElement('div');
38
+ msgDiv.classList.add('message', `${role}-message`);
39
+ msgDiv.textContent = text;
40
+ chatContainer.appendChild(msgDiv);
41
+ chatContainer.scrollTop = chatContainer.scrollHeight;
42
+ return msgDiv;
43
+ }
44
+
45
+ /**
46
+ * Adds a visual typing indicator
47
+ */
48
+ function addLoadingIndicator() {
49
+ const loader = document.createElement('div');
50
+ loader.classList.add('message', 'bot-message', 'loading-msg');
51
+ loader.innerHTML = `
52
+ <div class="typing-indicator">
53
+ <span></span><span></span><span></span>
54
+ </div>
55
+ `;
56
+ chatContainer.appendChild(loader);
57
+ chatContainer.scrollTop = chatContainer.scrollHeight;
58
+ return loader;
59
+ }
60
+
61
+ /**
62
+ * Main function to send message and get BYOK response
63
+ */
64
+ async function sendMessage() {
65
+ const text = userInput.value.trim();
66
+ if (!text) return;
67
+
68
+ // Persist settings to localStorage
69
+ localStorage.setItem('byok_api_key', apiKeyInput.value);
70
+ localStorage.setItem('byok_llm_model', llmModelInput.value);
71
+ localStorage.setItem('byok_embed_model', embedModelInput.value);
72
+
73
+ // Clear input and add user message
74
+ userInput.value = '';
75
+ userInput.style.height = 'auto';
76
+ addMessage(text, 'user');
77
+
78
+ // Add loading indicator
79
+ const loader = addLoadingIndicator();
80
+
81
+ try {
82
+ const response = await fetch(`${BACKEND_URL}/chat`, {
83
+ method: 'POST',
84
+ headers: { 'Content-Type': 'application/json' },
85
+ body: JSON.stringify({
86
+ message: text,
87
+ api_key: apiKeyInput.value || null,
88
+ llm_model: llmModelInput.value || null,
89
+ embed_model: embedModelInput.value || null
90
+ })
91
+ });
92
+
93
+ const data = await response.json();
94
+
95
+ // Remove loader and add bot response
96
+ loader.remove();
97
+ if (data.answer) {
98
+ addMessage(data.answer, 'bot');
99
+
100
+ // Update performance stats
101
+ const pipeTime = data.total_time ? data.total_time.toFixed(1) : '--';
102
+ const retTime = data.timings && data.timings.retrieval ? data.timings.retrieval.toFixed(2) : '--';
103
+ statsDisplay.textContent = `Pipeline: ${pipeTime}s | Retrieval: ${retTime}s`;
104
+ } else {
105
+ addMessage('Error: No response from engine.', 'bot');
106
+ }
107
+ } catch (err) {
108
+ if (loader) loader.remove();
109
+ addMessage(`Error: ${err.message}`, 'bot');
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Helper for suggestion buttons
115
+ */
116
+ function useSuggestion(text) {
117
+ userInput.value = text;
118
+ sendMessage();
119
+ }
120
+
121
+ // Event Listeners
122
+ sendBtn.addEventListener('click', sendMessage);
123
+
124
+ userInput.addEventListener('keydown', (e) => {
125
+ if (e.key === 'Enter' && !e.shiftKey) {
126
+ e.preventDefault();
127
+ sendMessage();
128
+ }
129
+ });
130
+
131
+ // Auto-resize textarea as user types
132
+ userInput.addEventListener('input', function () {
133
+ this.style.height = 'auto';
134
+ this.style.height = (this.scrollHeight) + 'px';
135
+ });