@quidgest/chatbot 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +43 -36
- package/dist/index.mjs +5321 -4375
- package/dist/style.css +1 -1
- package/package.json +3 -3
- package/src/assets/styles/styles.scss +1 -1
- package/src/components/CBMessage.vue +2 -6
- package/src/components/ChatBot.vue +80 -87
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.q-chatbot{width:100%;padding:1rem;display:flex;flex-direction:column;height:100%}.q-chatbot input{line-height:1.5rem}.q-chatbot .q-input-group .i-text__field{border-radius:0;flex:1}.q-chatbot__text p{margin:0}.q-chatbot__content{background-color:#fff;border:1px solid #eaebec;height:100%;width:100%;display:flex;gap:.75rem;flex-direction:column;overflow:hidden}.q-chatbot__footer-container{padding:.8rem}.q-chatbot__input-wrapper{display:flex;flex-direction:column;position:relative}.q-chatbot__image-preview{display:inline-flex;align-items:center;position:relative;margin-top:.5rem;width:fit-content}.q-chatbot__image-preview img{width:60px;height:60px;object-fit:cover;border-radius:4px;margin-right:.25rem;border:1px solid #eaebec;overflow:hidden}.q-chatbot__image-preview img:hover+.q-chatbot__remove-image,.q-chatbot__image-preview img:focus+.q-chatbot__remove-image{opacity:1;pointer-events:auto}.q-chatbot__image-preview img:focus{outline:solid rgb(var(--q-theme-info-rgb)/50%)}.q-chatbot .q-
|
|
1
|
+
.q-chatbot{width:100%;padding:1rem;display:flex;flex-direction:column;height:100%}.q-chatbot input{line-height:1.5rem}.q-chatbot .q-input-group .i-text__field{border-radius:0;flex:1}.q-chatbot__text p{margin:0}.q-chatbot__content{background-color:#fff;border:1px solid #eaebec;height:100%;width:100%;display:flex;gap:.75rem;flex-direction:column;overflow:hidden}.q-chatbot__footer-container{padding:.8rem}.q-chatbot__input-wrapper{display:flex;flex-direction:column;position:relative}.q-chatbot__image-preview{display:inline-flex;align-items:center;position:relative;margin-top:.5rem;width:fit-content}.q-chatbot__image-preview img{width:60px;height:60px;object-fit:cover;border-radius:4px;margin-right:.25rem;border:1px solid #eaebec;overflow:hidden}.q-chatbot__image-preview img:hover+.q-chatbot__remove-image,.q-chatbot__image-preview img:focus+.q-chatbot__remove-image{opacity:1;pointer-events:auto}.q-chatbot__image-preview img:focus{outline:solid rgb(var(--q-theme-info-rgb)/50%)}.q-chatbot .q-button.q-chatbot__remove-image{position:absolute;top:-5px;right:-5px;background-color:#00000080;color:#fff;border-radius:50%;padding:5px;font-size:12px;border:none;opacity:0;pointer-events:none;transition:opacity .2s ease-in-out}.q-chatbot .q-button.q-chatbot__remove-image:hover,.q-chatbot .q-button.q-chatbot__remove-image:focus{opacity:1;pointer-events:auto}.q-chatbot__send-container{padding-bottom:.25rem;display:flex;justify-content:space-between;width:100%}.q-chatbot__send-container .q-chatbot__send,.q-chatbot__send-container .q-chatbot__upload{border-radius:1rem}.q-chatbot__send-container .spacer{flex-grow:1}.q-chatbot__footer{position:sticky;padding:0 .5rem;border:1px solid #eaebec;border-radius:.25rem;bottom:0;width:100%;display:flex;flex-direction:column;gap:.25rem}.q-chatbot__footer-disabled{background-color:rgb(var(--q-theme-neutral-light-rgb)/.25);cursor:not-allowed}.q-chatbot__footer.drag-over{border:2px dashed rgb(var(--q-theme-primary-rgb)/.25);background-color:#018bd20d}.q-chatbot__footer .q-chatbot__input{min-height:50px;max-height:100px;border-bottom:1px solid #eaebec;overflow-y:auto}.q-chatbot__footer .q-text-area{max-height:100%;overflow-y:auto}.q-chatbot__footer .q-text-area .q-field__control{border:none}.q-chatbot__upload-container{display:flex;justify-content:flex-start;padding:.25rem 0}.q-chatbot__upload-container .q-chatbot__upload{border-radius:1rem}.q-chatbot__messages-container{display:flex;flex-direction:column;flex-grow:1;padding:0 1rem 2rem;gap:1.5rem;overflow-y:auto}.q-chatbot__messages-wrapper{display:flex;max-width:100%;gap:.2rem}.q-chatbot__tools{display:flex;flex-direction:row;justify-content:end;max-width:100%}.q-chatbot__message-wrapper{display:flex;flex-direction:column;gap:.2rem}.q-chatbot__message-container{display:flex;flex-direction:column;gap:.25rem}.q-chatbot__messages-wrapper_right{justify-content:flex-end}.q-chatbot__messages-wrapper_right .q-chatbot__message-container{align-items:flex-end}.q-chatbot__messages-wrapper_right .q-chatbot__message-wrapper{display:flex;align-items:flex-end}.q-chatbot__profile.q-icon__img{border-radius:50%;height:2rem;width:2rem}.q-chatbot__message{display:flex;align-items:center;padding:.3rem .5rem;background-color:#eaebec;width:fit-content;white-space:normal;min-height:2rem;word-wrap:break-word;word-break:break-word;border-radius:0 .5rem .5rem}.q-chatbot__messages-wrapper_right .q-chatbot__message{background-color:#018bd233;border-radius:.5rem 0 .5rem .5rem}.q-chatbot__sender{white-space:nowrap;color:#7c858d;font-size:.7rem}.q-chatbot__retry-button{align-items:center;display:flex}.q-chatbot__dialog-title{margin:.5rem 0}#comment-dialog .q-dialog__header,.hidden-input{display:none}.pulsing-dots{display:flex;align-items:center;justify-content:center;gap:.1rem}.dot{font-size:20px;line-height:1;animation:pulse 1s infinite;color:var(--q-theme-primary)}@keyframes pulse{0%,to{transform:scale(.8);opacity:.6}50%{transform:scale(1);opacity:1}}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quidgest/chatbot",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
7
7
|
"main": "dist/index.cjs",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"vue-tsc": "^1.8.27"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
|
-
"@quidgest/ui": "^0.
|
|
55
|
-
"vue": "3.5.13"
|
|
54
|
+
"@quidgest/ui": "^0.15.9",
|
|
55
|
+
"vue": "^3.5.13"
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -56,7 +56,6 @@
|
|
|
56
56
|
:title="props.texts.goodResponse"
|
|
57
57
|
borderless
|
|
58
58
|
:disabled="loading"
|
|
59
|
-
b-style="secondary"
|
|
60
59
|
@click="openFeedbackDialog(1)">
|
|
61
60
|
<q-icon icon="thumb-up" />
|
|
62
61
|
</q-button>
|
|
@@ -64,7 +63,6 @@
|
|
|
64
63
|
:title="props.texts.badResponse"
|
|
65
64
|
borderless
|
|
66
65
|
:disabled="loading"
|
|
67
|
-
b-style="secondary"
|
|
68
66
|
@click="openFeedbackDialog(0)">
|
|
69
67
|
<q-icon icon="thumb-down" />
|
|
70
68
|
</q-button>
|
|
@@ -72,7 +70,6 @@
|
|
|
72
70
|
:title="props.texts.copyResponse"
|
|
73
71
|
borderless
|
|
74
72
|
:disabled="loading"
|
|
75
|
-
b-style="secondary"
|
|
76
73
|
@click="copyResponse">
|
|
77
74
|
<q-icon icon="copy-content" />
|
|
78
75
|
</q-button>
|
|
@@ -187,7 +184,7 @@
|
|
|
187
184
|
action: submitFeedback,
|
|
188
185
|
props: {
|
|
189
186
|
label: props.texts.submitButton,
|
|
190
|
-
'
|
|
187
|
+
'variant': 'bold',
|
|
191
188
|
},
|
|
192
189
|
icon: {
|
|
193
190
|
icon: 'submit'
|
|
@@ -196,8 +193,7 @@
|
|
|
196
193
|
{
|
|
197
194
|
id: 'cancel-btn',
|
|
198
195
|
props: {
|
|
199
|
-
label: props.texts.cancelButton
|
|
200
|
-
'b-style': 'secondary',
|
|
196
|
+
label: props.texts.cancelButton
|
|
201
197
|
},
|
|
202
198
|
icon: {
|
|
203
199
|
icon: 'cancel'
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
<div class="q-chatbot__tools">
|
|
6
6
|
<q-button
|
|
7
7
|
:title="props.texts.clearChat"
|
|
8
|
-
b-style="secondary"
|
|
9
8
|
:disabled="isChatDisabled"
|
|
10
9
|
borderless
|
|
11
10
|
@click="clearChat">
|
|
@@ -55,7 +54,6 @@
|
|
|
55
54
|
<q-button
|
|
56
55
|
class="q-chatbot__remove-image"
|
|
57
56
|
tabindex="0"
|
|
58
|
-
b-style="secondary"
|
|
59
57
|
flat
|
|
60
58
|
round
|
|
61
59
|
@click="removeImage">
|
|
@@ -77,7 +75,6 @@
|
|
|
77
75
|
<!-- Upload button moved to the same container as send, but positioned to the left -->
|
|
78
76
|
<q-button
|
|
79
77
|
:title="props.texts.imageUpload"
|
|
80
|
-
b-style="secondary"
|
|
81
78
|
class="q-chatbot__upload"
|
|
82
79
|
:disabled="isChatDisabled || isLoading || hasSelectedImage"
|
|
83
80
|
@click="triggerImageUpload">
|
|
@@ -95,7 +92,7 @@
|
|
|
95
92
|
|
|
96
93
|
<q-button
|
|
97
94
|
:title="props.texts.sendMessage"
|
|
98
|
-
|
|
95
|
+
variant="bold"
|
|
99
96
|
class="q-chatbot__send"
|
|
100
97
|
:disabled="isSendButtonDisabled"
|
|
101
98
|
:readonly="isSendButtonDisabled"
|
|
@@ -194,49 +191,36 @@
|
|
|
194
191
|
}
|
|
195
192
|
|
|
196
193
|
async function initChat() {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
if(!response.data) {
|
|
203
|
-
addChatMessage(props.texts.loginError)
|
|
204
|
-
setDisabledState(true)
|
|
205
|
-
isLoading.value = false
|
|
206
|
-
return
|
|
207
|
-
}
|
|
194
|
+
try {
|
|
195
|
+
await axios.post(props.apiEndpoint + '/auth/login', {
|
|
196
|
+
username: props.username,
|
|
197
|
+
password: 'test'
|
|
198
|
+
})
|
|
208
199
|
|
|
209
|
-
|
|
200
|
+
loadChatData()
|
|
201
|
+
} catch (error) {
|
|
210
202
|
setDisabledState(true)
|
|
211
203
|
addChatMessage(props.texts.loginError)
|
|
212
|
-
console.log(
|
|
213
|
-
return
|
|
204
|
+
console.log('Error logging in: ' + error)
|
|
214
205
|
}
|
|
215
|
-
|
|
216
|
-
loadChatData()
|
|
217
206
|
};
|
|
218
207
|
|
|
219
208
|
async function loadChatData() {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
209
|
+
try {
|
|
210
|
+
const response = await axios.post(props.apiEndpoint + '/prompt/load', {
|
|
211
|
+
username: props.username,
|
|
212
|
+
project: props.projectPath
|
|
213
|
+
});
|
|
224
214
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
if (response.status !== 200 || !response.data.success) {
|
|
234
|
-
setDisabledState(true)
|
|
235
|
-
addChatMessage(props.texts.loginError)
|
|
236
|
-
console.log(`Unsuccessful load, endpoint gave status ${response.status}`)
|
|
237
|
-
return
|
|
215
|
+
if(!response) return console.error('No response from server');
|
|
216
|
+
|
|
217
|
+
if (response.status !== 200 || !response.data.success) {
|
|
218
|
+
setDisabledState(true)
|
|
219
|
+
addChatMessage(props.texts.botIsSick)
|
|
220
|
+
console.log(`Unsuccessful load, endpoint gave status ${response.status}`)
|
|
221
|
+
return
|
|
238
222
|
}
|
|
239
|
-
|
|
223
|
+
|
|
240
224
|
sendInitialMessage()
|
|
241
225
|
response.data.history.forEach((message: ChatBotMessageContent) => {
|
|
242
226
|
const imgUrl = message.imageUrl ? props.controllerEndpoint + message.imageUrl : undefined
|
|
@@ -244,9 +228,15 @@
|
|
|
244
228
|
message.content,
|
|
245
229
|
message.type === 'ai' ? 'bot' : 'user',
|
|
246
230
|
imgUrl,
|
|
247
|
-
message.sessionID
|
|
248
|
-
)
|
|
249
|
-
|
|
231
|
+
message.sessionID)
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
} catch(error) {
|
|
235
|
+
setDisabledState(true)
|
|
236
|
+
addChatMessage(props.texts.botIsSick)
|
|
237
|
+
console.log('Error loading: ' + error)
|
|
238
|
+
}
|
|
239
|
+
|
|
250
240
|
}
|
|
251
241
|
|
|
252
242
|
// Modified addChatMessage to add isStreaming flag for empty bot messages
|
|
@@ -379,47 +369,50 @@
|
|
|
379
369
|
|
|
380
370
|
isLoading.value = true
|
|
381
371
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
372
|
+
try {
|
|
373
|
+
const response = await axios.post(props.apiEndpoint + '/prompt/submit', formData, {
|
|
374
|
+
headers: {
|
|
375
|
+
'Content-Type': 'text/event-stream',
|
|
376
|
+
'Accept': 'text/event-stream',
|
|
377
|
+
},
|
|
378
|
+
responseType: 'stream',
|
|
379
|
+
adapter: 'fetch',
|
|
380
|
+
})
|
|
390
381
|
|
|
391
|
-
|
|
392
|
-
addChatMessage(props.texts.botIsSick)
|
|
393
|
-
setDisabledState(true)
|
|
394
|
-
isLoading.value = false
|
|
395
|
-
return
|
|
396
|
-
}
|
|
382
|
+
if(!response) return console.error('No response from server')
|
|
397
383
|
|
|
398
|
-
|
|
399
|
-
|
|
384
|
+
const reader = response.data.getReader()
|
|
385
|
+
const decoder = new TextDecoder("utf-8")
|
|
400
386
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
387
|
+
while(true) {
|
|
388
|
+
const { done, value } = await reader.read()
|
|
389
|
+
if(done) break
|
|
390
|
+
|
|
391
|
+
const chunk = decoder.decode(value, { stream: true })
|
|
392
|
+
const eventList = chunk.match(/data:\s*({.*?})/g)
|
|
393
|
+
if(!eventList) continue
|
|
408
394
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
395
|
+
for(const event of eventList) {
|
|
396
|
+
try {
|
|
397
|
+
const rawData = event.split('data:')[1].trim()
|
|
398
|
+
const data = JSON.parse(rawData)
|
|
399
|
+
if(msg) {
|
|
400
|
+
msg.message += data.value
|
|
401
|
+
}
|
|
402
|
+
} catch (error) {
|
|
403
|
+
console.error('Error parsing match:', error)
|
|
415
404
|
}
|
|
416
|
-
} catch (error) {
|
|
417
|
-
console.error('Error parsing match:', error)
|
|
418
405
|
}
|
|
406
|
+
if(autoScrollEnabled.value) scrollToBottom()
|
|
419
407
|
}
|
|
420
|
-
|
|
408
|
+
|
|
409
|
+
isLoading.value = false
|
|
410
|
+
} catch (error) {
|
|
411
|
+
setDisabledState(true)
|
|
412
|
+
addChatMessage(props.texts.botIsSick)
|
|
413
|
+
console.log('Error setting chat prompt: ' + error)
|
|
414
|
+
return
|
|
421
415
|
}
|
|
422
|
-
isLoading.value = false
|
|
423
416
|
}
|
|
424
417
|
|
|
425
418
|
function clearChat() {
|
|
@@ -427,21 +420,21 @@
|
|
|
427
420
|
username: props.username,
|
|
428
421
|
project: props.projectPath
|
|
429
422
|
})
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
setDisabledState(true)
|
|
433
|
-
addChatMessage(props.texts.loginError)
|
|
434
|
-
console.log(`Unsuccessful clear, endpoint gave status ${response.status}`)
|
|
435
|
-
return
|
|
436
|
-
}
|
|
437
|
-
resetChat()
|
|
438
|
-
sendInitialMessage()
|
|
439
|
-
})
|
|
440
|
-
.catch((error: Error) => {
|
|
423
|
+
.then((response: AxiosResponse) => {
|
|
424
|
+
if (response.status !== 200 || !response.data.success) {
|
|
441
425
|
setDisabledState(true)
|
|
442
426
|
addChatMessage(props.texts.loginError)
|
|
443
|
-
console.log(
|
|
444
|
-
|
|
427
|
+
console.log(`Unsuccessful clear, endpoint gave status ${response.status}`)
|
|
428
|
+
return
|
|
429
|
+
}
|
|
430
|
+
resetChat()
|
|
431
|
+
sendInitialMessage()
|
|
432
|
+
})
|
|
433
|
+
.catch((error: Error) => {
|
|
434
|
+
setDisabledState(true)
|
|
435
|
+
addChatMessage(props.texts.loginError)
|
|
436
|
+
console.log('Error clearing chat: ' + error)
|
|
437
|
+
})
|
|
445
438
|
}
|
|
446
439
|
|
|
447
440
|
function getMessageClasses(sender: ChatBotMessageSender) {
|