pvanand commited on
Commit
0c13220
·
verified ·
1 Parent(s): d4ebc98

Create followup-agent.html

Browse files
Files changed (1) hide show
  1. static/followup-agent.html +330 -0
static/followup-agent.html ADDED
@@ -0,0 +1,330 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>AI Chatbot</title>
7
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
8
+ <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
9
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/uuid/8.3.2/uuid.min.js"></script>
10
+ <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
11
+ <style>
12
+ :root {
13
+ --accent-color: #003366; /* Navy blue */
14
+ }
15
+ body {
16
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
17
+ line-height: 1.6;
18
+ margin: 0 auto;
19
+ padding: 0px;
20
+ background-color: #f5f7fa;
21
+ color: #333;
22
+ }
23
+ h2 {
24
+ color: var(--accent-color);
25
+ border-bottom: 2px solid var(--accent-color);
26
+ padding-bottom: 10px;
27
+ margin-top: 0;
28
+ }
29
+ #app {
30
+ max-width: 900px;
31
+ margin: 0 auto;
32
+ padding: 20px;
33
+ }
34
+ .chat-container {
35
+ background-color: #ffffff;
36
+ border-radius: 10px;
37
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
38
+ overflow: hidden;
39
+ display: flex;
40
+ flex-direction: column;
41
+ height: 98vh;
42
+ }
43
+ .messages {
44
+ flex-grow: 1;
45
+ overflow-y: auto;
46
+ padding: 20px;
47
+ display: flex;
48
+ flex-direction: column;
49
+ }
50
+ .message {
51
+ max-width: 80%;
52
+ margin-bottom: 20px;
53
+ padding: 12px 16px;
54
+ border-radius: 18px;
55
+ font-size: 14px;
56
+ line-height: 1.4;
57
+ word-wrap: break-word;
58
+ overflow-wrap: break-word;
59
+ }
60
+ .user-message {
61
+ background-color: #5c656e;
62
+ color: #ffffff;
63
+ align-self: flex-end;
64
+ }
65
+ .bot-message {
66
+ background-color: #f0f2f5;
67
+ color: #333;
68
+ align-self: flex-start;
69
+ background-color: #ffffff;
70
+ padding: 30px;
71
+ border-radius: 8px;
72
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
73
+ overflow-wrap: break-word;
74
+ word-wrap: break-word;
75
+ word-break: break-word;
76
+ }
77
+ .input-area {
78
+ display: flex;
79
+ padding: 20px;
80
+ background-color: #ffffff;
81
+ border-top: 1px solid #e0e0e0;
82
+ }
83
+ #user-input {
84
+ flex-grow: 1;
85
+ padding: 12px;
86
+ border: 1px solid #d0d0d0;
87
+ border-radius: 20px;
88
+ font-size: 14px;
89
+ outline: none;
90
+ }
91
+ .send-button {
92
+ background-color: #007bff;
93
+ color: #ffffff;
94
+ border: none;
95
+ border-radius: 50%;
96
+ width: 40px;
97
+ height: 40px;
98
+ margin-left: 10px;
99
+ cursor: pointer;
100
+ display: flex;
101
+ align-items: center;
102
+ justify-content: center;
103
+ transition: background-color 0.3s;
104
+ }
105
+ .send-button:hover {
106
+ background-color: #0056b3;
107
+ }
108
+ .send-button svg {
109
+ width: 20px;
110
+ height: 20px;
111
+ }
112
+ .reset-button {
113
+ background-color: #f44336;
114
+ color: #ffffff;
115
+ border: none;
116
+ border-radius: 20px;
117
+ padding: 8px 16px;
118
+ margin-left: 10px;
119
+ cursor: pointer;
120
+ font-size: 14px;
121
+ transition: background-color 0.3s;
122
+ }
123
+ .reset-button:hover {
124
+ background-color: #d32f2f;
125
+ }
126
+ .option-buttons {
127
+ display: flex;
128
+ flex-wrap: wrap;
129
+ gap: 10px;
130
+ margin-bottom: 15px;
131
+ }
132
+ .option-button {
133
+ background-color: #f0f2f5;
134
+ border: 1px solid #d0d0d0;
135
+ border-radius: 20px;
136
+ padding: 8px 16px;
137
+ font-size: 14px;
138
+ cursor: pointer;
139
+ transition: background-color 0.3s, transform 0.1s;
140
+ }
141
+ .option-button:hover {
142
+ background-color: #e4e6e9;
143
+ transform: translateY(-2px);
144
+ }
145
+ .option-button:active {
146
+ transform: translateY(0);
147
+ }
148
+ .option-button.selected {
149
+ background-color: #c0c4c9;
150
+ border-color: #a0a4a9;
151
+ }
152
+ @media (max-width: 600px) {
153
+ #app {
154
+ padding: 10px;
155
+ }
156
+ .chat-container {
157
+ height: 90vh;
158
+ }
159
+ .message {
160
+ max-width: 90%;
161
+ }
162
+ }
163
+ </style>
164
+ </head>
165
+ <body>
166
+ <div id="app">
167
+ <div class="chat-container">
168
+ <div class="messages" ref="messageContainer">
169
+ <div v-for="(message, index) in messages" :key="index"
170
+ :class="['message', message.type === 'user' ? 'user-message' : 'bot-message']"
171
+ v-html="message.content">
172
+ </div>
173
+ </div>
174
+ <div class="input-area">
175
+ <input type="text" id="user-input" v-model="userInput" @keyup.enter="sendMessage" placeholder="Type your message...">
176
+ <button class="send-button" @click="sendMessage">
177
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
178
+ <line x1="22" y1="2" x2="11" y2="13"></line>
179
+ <polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
180
+ </svg>
181
+ </button>
182
+ <button class="reset-button" @click="resetConversation">Reset</button>
183
+ </div>
184
+ </div>
185
+ </div>
186
+
187
+ <script>
188
+ marked.setOptions({
189
+ sanitize: false
190
+ });
191
+
192
+ const app = new Vue({
193
+ el: '#app',
194
+ data: {
195
+ messages: [],
196
+ userInput: '',
197
+ selectedOptions: {},
198
+ conversationId: '',
199
+ },
200
+ methods: {
201
+ async sendMessage() {
202
+ if (!this.userInput.trim()) return;
203
+
204
+ this.messages.push({ type: 'user', content: marked.parse(this.userInput) });
205
+ const message = this.userInput;
206
+ this.userInput = '';
207
+ this.selectedOptions = {};
208
+
209
+ try {
210
+ const response = await fetch('https://pvanand-general-chat.hf.space/followup-agent', {
211
+ method: 'POST',
212
+ headers: {
213
+ 'Content-Type': 'application/json',
214
+ 'X-API-Key': '44d5c2ac18ced6fc25c1e57dcd06fc0b31fb4ad97bf56e67540671a647465df4'
215
+ },
216
+ body: JSON.stringify({
217
+ query: message,
218
+ model_id: 'openai/gpt-4o-mini',
219
+ conversation_id: this.conversationId,
220
+ user_id: 'string'
221
+ })
222
+ });
223
+
224
+ const reader = response.body.getReader();
225
+ let rawResponse = '';
226
+ let streamingIndex = this.messages.push({ type: 'bot', content: 'Thinking...' }) - 1;
227
+
228
+ while (true) {
229
+ const { done, value } = await reader.read();
230
+ if (done) break;
231
+
232
+ const chunk = new TextDecoder().decode(value);
233
+ rawResponse += chunk;
234
+ this.$set(this.messages, streamingIndex, { type: 'bot', content: marked.parse(rawResponse) });
235
+ }
236
+
237
+ // Remove the streaming message
238
+ this.messages.splice(streamingIndex, 1);
239
+
240
+ const jsonStart = rawResponse.lastIndexOf('\n\n');
241
+ if (jsonStart !== -1) {
242
+ const jsonStr = rawResponse.slice(jsonStart + 2);
243
+ const parsedResponse = JSON.parse(jsonStr);
244
+ this.renderParsedResponse(parsedResponse);
245
+ }
246
+ } catch (error) {
247
+ console.error('Error:', error);
248
+ this.messages.push({ type: 'bot', content: 'An error occurred while processing your request.' });
249
+ }
250
+ this.$nextTick(() => this.scrollToBottom());
251
+ },
252
+ renderParsedResponse(parsedResponse) {
253
+ let botResponse = '';
254
+
255
+ if (parsedResponse.response) {
256
+ botResponse += parsedResponse.response + '\n\n';
257
+ }
258
+
259
+ if (parsedResponse.clarification) {
260
+ parsedResponse.clarification.forEach((item, questionIndex) => {
261
+ botResponse += `**${item.question}**\n\n`;
262
+ botResponse += '<div class="option-buttons">';
263
+ item.options.forEach((option, optionIndex) => {
264
+ const escapedOption = option.replace(/'/g, "\\'");
265
+ botResponse += `<button class="option-button" onclick="app.toggleOption('${escapedOption}', ${questionIndex}, ${optionIndex})">${option}</button>`;
266
+ });
267
+ botResponse += '</div>\n\n';
268
+ });
269
+ }
270
+
271
+ if (botResponse) {
272
+ this.messages.push({ type: 'bot', content: marked.parse(botResponse) });
273
+ }
274
+ this.$nextTick(() => {
275
+ this.scrollToBottom();
276
+ this.updateButtonStates();
277
+ });
278
+ },
279
+ toggleOption(option, questionIndex, optionIndex) {
280
+ if (!this.selectedOptions[questionIndex]) {
281
+ this.$set(this.selectedOptions, questionIndex, []);
282
+ }
283
+
284
+ const index = this.selectedOptions[questionIndex].indexOf(option);
285
+ if (index > -1) {
286
+ this.selectedOptions[questionIndex].splice(index, 1);
287
+ } else {
288
+ this.selectedOptions[questionIndex].push(option);
289
+ }
290
+
291
+ this.updateInputFromSelectedOptions();
292
+ this.updateButtonStates();
293
+ },
294
+ updateInputFromSelectedOptions() {
295
+ this.userInput = Object.entries(this.selectedOptions)
296
+ .map(([questionIndex, options]) =>
297
+ `Q${parseInt(questionIndex) + 1}: ${options.join(', ')}`)
298
+ .join(' | ');
299
+ this.$nextTick(() => document.getElementById('user-input').focus());
300
+ },
301
+ updateButtonStates() {
302
+ Object.entries(this.selectedOptions).forEach(([questionIndex, options]) => {
303
+ const buttons = document.querySelectorAll(`.option-buttons:nth-of-type(${parseInt(questionIndex) + 1}) .option-button`);
304
+ buttons.forEach((button) => {
305
+ if (options.includes(button.textContent)) {
306
+ button.classList.add('selected');
307
+ } else {
308
+ button.classList.remove('selected');
309
+ }
310
+ });
311
+ });
312
+ },
313
+ resetConversation() {
314
+ this.conversationId = uuid.v4();
315
+ this.messages = [{ type: 'bot', content: 'Conversation reset. How can I help you?' }];
316
+ this.selectedOptions = {};
317
+ this.userInput = '';
318
+ },
319
+ scrollToBottom() {
320
+ const container = this.$refs.messageContainer;
321
+ container.scrollTop = container.scrollHeight;
322
+ }
323
+ },
324
+ mounted() {
325
+ this.resetConversation();
326
+ }
327
+ });
328
+ </script>
329
+ </body>
330
+ </html>