@quidgest/chatbot 0.0.5 → 0.0.7
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/README.md +8 -0
- package/dist/components/CBMessage.vue.d.ts +8 -4
- package/dist/components/ChatBot.vue.d.ts +10 -5
- package/dist/components/index.d.ts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +9 -4298
- package/dist/index.mjs +1914 -3573
- package/dist/style.css +1 -96
- package/package.json +11 -7
- package/src/assets/styles/styles.scss +7 -11
- package/src/components/CBMessage.vue +29 -6
- package/src/components/ChatBot.vue +131 -117
- package/src/components/index.ts +3 -6
- package/src/types/message.type.ts +5 -5
- package/src/types/texts.type.ts +1 -1
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
onMounted,
|
|
4
|
+
nextTick,
|
|
5
|
+
computed,
|
|
6
|
+
ref,
|
|
7
|
+
watch,
|
|
8
|
+
defineOptions
|
|
9
|
+
} from 'vue'
|
|
3
10
|
import type { Ref } from 'vue'
|
|
4
11
|
import Axios from 'axios'
|
|
5
12
|
import type { AxiosResponse } from 'axios'
|
|
@@ -7,31 +14,33 @@
|
|
|
7
14
|
|
|
8
15
|
import {
|
|
9
16
|
QButton,
|
|
10
|
-
QTextField,
|
|
17
|
+
QTextField,
|
|
11
18
|
QInputGroup,
|
|
12
19
|
QIcon
|
|
13
|
-
} from '@quidgest/ui'
|
|
20
|
+
} from '@quidgest/ui/components'
|
|
14
21
|
|
|
15
22
|
import type { ResourceStrings } from '@/types/texts.type'
|
|
16
|
-
import type {
|
|
17
|
-
|
|
23
|
+
import type {
|
|
24
|
+
ChatBotMessage,
|
|
25
|
+
ChatBotMessageContent
|
|
26
|
+
} from '@/types/message.type'
|
|
18
27
|
|
|
19
28
|
let messages: Ref<ChatBotMessage[]> = ref([])
|
|
20
29
|
let msgHistoryStack: string[] = []
|
|
21
30
|
let nextMessageId: number = 1
|
|
22
31
|
let userPrompt: Ref<string> = ref('')
|
|
32
|
+
let isLoading: Ref<boolean> = ref(false)
|
|
23
33
|
let isChatDisabled: boolean = false
|
|
24
|
-
|
|
25
|
-
|
|
34
|
+
|
|
26
35
|
// refs
|
|
27
|
-
const
|
|
36
|
+
const scrollElement = ref<HTMLElement | null>(null)
|
|
28
37
|
const promptInput = ref<HTMLInputElement | null>(null)
|
|
29
38
|
|
|
30
39
|
export type ChatBotProps = {
|
|
31
40
|
/**
|
|
32
41
|
* API Enpoint URL
|
|
33
42
|
*/
|
|
34
|
-
apiEndpoint?: string
|
|
43
|
+
apiEndpoint?: string
|
|
35
44
|
|
|
36
45
|
/**
|
|
37
46
|
* Static resource texts used by ChatBot
|
|
@@ -47,6 +56,11 @@
|
|
|
47
56
|
* Project aplication path
|
|
48
57
|
*/
|
|
49
58
|
projectPath: string
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Project locale
|
|
62
|
+
*/
|
|
63
|
+
dateFormat?: string
|
|
50
64
|
}
|
|
51
65
|
|
|
52
66
|
const props = withDefaults(defineProps<ChatBotProps>(), {
|
|
@@ -66,7 +80,6 @@
|
|
|
66
80
|
|
|
67
81
|
onMounted(() => {
|
|
68
82
|
initChat()
|
|
69
|
-
nextTick(scrollChatToBottom)
|
|
70
83
|
})
|
|
71
84
|
|
|
72
85
|
const userMessages = computed(() => {
|
|
@@ -76,31 +89,31 @@
|
|
|
76
89
|
function setDisabledState(state: boolean) {
|
|
77
90
|
isChatDisabled = state
|
|
78
91
|
}
|
|
79
|
-
|
|
92
|
+
|
|
80
93
|
function initChat() {
|
|
81
94
|
Axios.post(props.apiEndpoint + '/auth/login', {
|
|
82
95
|
username: props.username,
|
|
83
96
|
password: 'test'
|
|
84
97
|
})
|
|
85
|
-
|
|
86
|
-
|
|
98
|
+
.then((response: AxiosResponse) => {
|
|
99
|
+
if (response.status != 200 || !response.data.success) {
|
|
100
|
+
setDisabledState(true)
|
|
101
|
+
addChatMessage(props.texts.loginError)
|
|
102
|
+
return console.log(
|
|
103
|
+
`Unsuccessful login, endpoint gave status ${response.status}`
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
loadChatData()
|
|
108
|
+
})
|
|
109
|
+
.catch((error: Error) => {
|
|
87
110
|
setDisabledState(true)
|
|
88
111
|
addChatMessage(props.texts.loginError)
|
|
89
|
-
|
|
90
|
-
|
|
112
|
+
console.log(
|
|
113
|
+
'The following error ocurred while trying to login: \n' +
|
|
114
|
+
error
|
|
91
115
|
)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
loadChatData()
|
|
95
|
-
})
|
|
96
|
-
.catch((error: Error) => {
|
|
97
|
-
setDisabledState(true)
|
|
98
|
-
addChatMessage(props.texts.loginError)
|
|
99
|
-
console.log(
|
|
100
|
-
'The following error ocurred while trying to login: \n' +
|
|
101
|
-
error
|
|
102
|
-
)
|
|
103
|
-
})
|
|
116
|
+
})
|
|
104
117
|
}
|
|
105
118
|
|
|
106
119
|
function loadChatData() {
|
|
@@ -108,28 +121,33 @@
|
|
|
108
121
|
username: props.username,
|
|
109
122
|
project: props.projectPath
|
|
110
123
|
})
|
|
111
|
-
|
|
112
|
-
|
|
124
|
+
.then((response: AxiosResponse) => {
|
|
125
|
+
if (response.status != 200 || !response.data.success) {
|
|
126
|
+
setDisabledState(true)
|
|
127
|
+
addChatMessage(props.texts.loginError)
|
|
128
|
+
return console.log(
|
|
129
|
+
`Unsuccessful load, endpoint gave status ${response.status}`
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
sendInitialMessage()
|
|
134
|
+
response.data.history.forEach(
|
|
135
|
+
(message: ChatBotMessageContent) => {
|
|
136
|
+
addChatMessage(
|
|
137
|
+
message.content,
|
|
138
|
+
message.type === 'ai' ? 'bot' : 'user'
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
)
|
|
142
|
+
})
|
|
143
|
+
.catch((error: Error) => {
|
|
113
144
|
setDisabledState(true)
|
|
114
145
|
addChatMessage(props.texts.loginError)
|
|
115
|
-
|
|
116
|
-
|
|
146
|
+
console.log(
|
|
147
|
+
'The following error ocurred while trying to login: \n' +
|
|
148
|
+
error
|
|
117
149
|
)
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
sendInitialMessage()
|
|
121
|
-
response.data.history.forEach((message: ChatBotMessageContent) => {
|
|
122
|
-
addChatMessage(message.content, message.type === "ai" ? "bot" : "user")
|
|
123
150
|
})
|
|
124
|
-
})
|
|
125
|
-
.catch((error: Error) => {
|
|
126
|
-
setDisabledState(true)
|
|
127
|
-
addChatMessage(props.texts.loginError)
|
|
128
|
-
console.log(
|
|
129
|
-
'The following error ocurred while trying to login: \n' +
|
|
130
|
-
error
|
|
131
|
-
)
|
|
132
|
-
})
|
|
133
151
|
}
|
|
134
152
|
|
|
135
153
|
function addChatMessage(message: string, sender: 'bot' | 'user' = 'bot') {
|
|
@@ -139,6 +157,8 @@
|
|
|
139
157
|
date: new Date(),
|
|
140
158
|
sender: sender
|
|
141
159
|
})
|
|
160
|
+
|
|
161
|
+
nextTick(scrollToBottom)
|
|
142
162
|
}
|
|
143
163
|
|
|
144
164
|
function getLastMessage() {
|
|
@@ -155,23 +175,16 @@
|
|
|
155
175
|
messages.value = []
|
|
156
176
|
msgHistoryStack = []
|
|
157
177
|
userPrompt.value = ''
|
|
158
|
-
isLoading = false
|
|
178
|
+
isLoading.value = false
|
|
159
179
|
setDisabledState(false)
|
|
160
180
|
}
|
|
161
181
|
|
|
162
|
-
function
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
const element = messagesContainer.value
|
|
166
|
-
setTimeout(
|
|
167
|
-
() =>
|
|
168
|
-
(element.scrollIntoView(false)),
|
|
169
|
-
100
|
|
170
|
-
)
|
|
182
|
+
function scrollToBottom() {
|
|
183
|
+
scrollElement.value?.scrollIntoView({ behavior: 'smooth' })
|
|
171
184
|
}
|
|
172
185
|
|
|
173
186
|
function handleKey(event: KeyboardEvent) {
|
|
174
|
-
if(promptInput.value == null) return
|
|
187
|
+
if (promptInput.value == null) return
|
|
175
188
|
|
|
176
189
|
if (event.key == 'ArrowUp') {
|
|
177
190
|
//No user messages, no need to continue
|
|
@@ -180,9 +193,7 @@
|
|
|
180
193
|
//Get next message to read
|
|
181
194
|
let lastMsgObj =
|
|
182
195
|
userMessages.value[
|
|
183
|
-
userMessages.value.length -
|
|
184
|
-
1 -
|
|
185
|
-
msgHistoryStack.length
|
|
196
|
+
userMessages.value.length - 1 - msgHistoryStack.length
|
|
186
197
|
]
|
|
187
198
|
|
|
188
199
|
//No more messages to go through
|
|
@@ -211,18 +222,17 @@
|
|
|
211
222
|
userPrompt.value = previousHistoryText
|
|
212
223
|
}
|
|
213
224
|
}
|
|
214
|
-
|
|
225
|
+
|
|
215
226
|
function sendMessage() {
|
|
216
227
|
if (
|
|
217
228
|
userPrompt.value.trim().length == 0 ||
|
|
218
|
-
isLoading ||
|
|
229
|
+
isLoading.value ||
|
|
219
230
|
isChatDisabled
|
|
220
231
|
)
|
|
221
232
|
return
|
|
222
233
|
|
|
223
234
|
addChatMessage(userPrompt.value, 'user')
|
|
224
235
|
|
|
225
|
-
scrollChatToBottom()
|
|
226
236
|
setChatPrompt(userPrompt.value)
|
|
227
237
|
|
|
228
238
|
userPrompt.value = '' //Clear user input
|
|
@@ -239,33 +249,33 @@
|
|
|
239
249
|
user: props.username
|
|
240
250
|
}
|
|
241
251
|
|
|
242
|
-
isLoading = true
|
|
252
|
+
isLoading.value = true
|
|
243
253
|
Axios({
|
|
244
254
|
url: props.apiEndpoint + '/prompt/message',
|
|
245
255
|
method: 'POST',
|
|
246
256
|
data: params,
|
|
247
257
|
onDownloadProgress: (progressEvent) => {
|
|
248
|
-
const chunk =
|
|
249
|
-
progressEvent.event?.currentTarget.response
|
|
258
|
+
const chunk = progressEvent.event?.currentTarget.response
|
|
250
259
|
const status = progressEvent.event?.currentTarget.status
|
|
251
260
|
|
|
252
261
|
if (status != 200) return
|
|
253
262
|
|
|
254
263
|
if (msg) msg.message = chunk
|
|
264
|
+
scrollToBottom()
|
|
255
265
|
}
|
|
256
266
|
})
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
267
|
+
.then(({ data }) => {
|
|
268
|
+
if (msg) msg.message = data
|
|
269
|
+
})
|
|
270
|
+
.catch((error) => {
|
|
271
|
+
addChatMessage(props.texts.botIsSick)
|
|
262
272
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
273
|
+
setDisabledState(true)
|
|
274
|
+
console.log(error)
|
|
275
|
+
})
|
|
276
|
+
.finally(() => {
|
|
277
|
+
isLoading.value = false
|
|
278
|
+
})
|
|
269
279
|
}
|
|
270
280
|
|
|
271
281
|
function setCursorPosition(elem: HTMLInputElement, pos: number) {
|
|
@@ -273,67 +283,65 @@
|
|
|
273
283
|
elem.setSelectionRange(pos, pos)
|
|
274
284
|
}
|
|
275
285
|
|
|
276
|
-
function clearChat() {
|
|
286
|
+
function clearChat() {
|
|
277
287
|
Axios.post(props.apiEndpoint + '/prompt/clear', {
|
|
278
288
|
username: props.username,
|
|
279
289
|
project: props.projectPath
|
|
280
290
|
})
|
|
281
|
-
|
|
282
|
-
|
|
291
|
+
.then((response: AxiosResponse) => {
|
|
292
|
+
if (response.status != 200 || !response.data.success) {
|
|
293
|
+
setDisabledState(true)
|
|
294
|
+
addChatMessage(props.texts.loginError)
|
|
295
|
+
return console.log(
|
|
296
|
+
`Unsuccessful login, endpoint gave status ${response.status}`
|
|
297
|
+
)
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
resetChat()
|
|
301
|
+
sendInitialMessage()
|
|
302
|
+
})
|
|
303
|
+
.catch((error: Error) => {
|
|
283
304
|
setDisabledState(true)
|
|
284
305
|
addChatMessage(props.texts.loginError)
|
|
285
|
-
|
|
286
|
-
|
|
306
|
+
console.log(
|
|
307
|
+
'The following error ocurred while trying to communicate with the endpoint: \n' +
|
|
308
|
+
error
|
|
287
309
|
)
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
resetChat()
|
|
291
|
-
sendInitialMessage()
|
|
292
|
-
})
|
|
293
|
-
.catch((error: Error) => {
|
|
294
|
-
setDisabledState(true)
|
|
295
|
-
addChatMessage(props.texts.loginError)
|
|
296
|
-
console.log(
|
|
297
|
-
'The following error ocurred while trying to communicate with the endpoint: \n' +
|
|
298
|
-
error
|
|
299
|
-
)
|
|
300
|
-
})
|
|
310
|
+
})
|
|
301
311
|
}
|
|
302
312
|
|
|
303
313
|
function getMessageClasses(sender: 'user' | 'bot') {
|
|
304
314
|
const classes: string[] = ['q-chatbot__messages-wrapper']
|
|
305
315
|
|
|
306
|
-
if(sender == 'user')
|
|
307
|
-
classes.push('q-chatbot__messages-wrapper_right')
|
|
316
|
+
if (sender == 'user') classes.push('q-chatbot__messages-wrapper_right')
|
|
308
317
|
|
|
309
318
|
return classes
|
|
310
319
|
}
|
|
311
320
|
|
|
312
|
-
watch(
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
321
|
+
watch(
|
|
322
|
+
() => props.apiEndpoint,
|
|
323
|
+
() => {
|
|
324
|
+
resetChat()
|
|
325
|
+
initChat()
|
|
326
|
+
}
|
|
327
|
+
)
|
|
316
328
|
|
|
317
329
|
defineOptions({ name: 'ChatBot' })
|
|
318
330
|
</script>
|
|
319
331
|
|
|
320
332
|
<template>
|
|
321
333
|
<div class="q-chatbot">
|
|
322
|
-
<div
|
|
323
|
-
ref="messagesContainer"
|
|
324
|
-
class="q-chatbot__content">
|
|
325
|
-
|
|
334
|
+
<div class="q-chatbot__content">
|
|
326
335
|
<!-- Chat tools -->
|
|
327
336
|
<div class="q-chatbot__tools">
|
|
328
|
-
<
|
|
337
|
+
<QButton
|
|
329
338
|
:title="props.texts.qButtonTitle"
|
|
330
|
-
b-style="
|
|
331
|
-
class="clear-btn"
|
|
339
|
+
b-style="secondary"
|
|
332
340
|
:disabled="isChatDisabled"
|
|
333
341
|
borderless
|
|
334
342
|
@click="clearChat">
|
|
335
|
-
<
|
|
336
|
-
</
|
|
343
|
+
<QIcon icon="bin" />
|
|
344
|
+
</QButton>
|
|
337
345
|
</div>
|
|
338
346
|
|
|
339
347
|
<div class="q-chatbot__messages-container">
|
|
@@ -341,15 +349,20 @@
|
|
|
341
349
|
v-for="message in messages"
|
|
342
350
|
:key="message.id"
|
|
343
351
|
:class="getMessageClasses(message.sender)">
|
|
344
|
-
<CBMessage
|
|
352
|
+
<CBMessage
|
|
353
|
+
v-bind="message"
|
|
354
|
+
:date-format="props.dateFormat"
|
|
355
|
+
:loading="isLoading && !message.message" />
|
|
345
356
|
</div>
|
|
346
357
|
</div>
|
|
358
|
+
|
|
359
|
+
<div ref="scrollElement"></div>
|
|
347
360
|
</div>
|
|
348
361
|
|
|
349
|
-
<
|
|
362
|
+
<QInputGroup
|
|
350
363
|
size="block"
|
|
351
364
|
:disabled="isChatDisabled">
|
|
352
|
-
<
|
|
365
|
+
<QTextField
|
|
353
366
|
ref="promptInput"
|
|
354
367
|
v-model="userPrompt"
|
|
355
368
|
class="q-chatbot__input"
|
|
@@ -359,15 +372,16 @@
|
|
|
359
372
|
@keydown="handleKey" />
|
|
360
373
|
|
|
361
374
|
<template #append>
|
|
362
|
-
<
|
|
375
|
+
<QButton
|
|
363
376
|
:title="props.texts.qButtonTitle"
|
|
364
377
|
b-style="primary"
|
|
365
378
|
class="q-chatbot__send"
|
|
366
|
-
:disabled="isChatDisabled"
|
|
379
|
+
:disabled="isChatDisabled || isLoading"
|
|
380
|
+
:loading="isLoading"
|
|
367
381
|
@click="sendMessage">
|
|
368
|
-
<
|
|
369
|
-
</
|
|
382
|
+
<QIcon icon="send" />
|
|
383
|
+
</QButton>
|
|
370
384
|
</template>
|
|
371
|
-
</
|
|
385
|
+
</QInputGroup>
|
|
372
386
|
</div>
|
|
373
387
|
</template>
|
package/src/components/index.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import CBMessage from
|
|
2
|
-
import type { CBMessageProps } from
|
|
1
|
+
import CBMessage from './CBMessage.vue'
|
|
2
|
+
import type { CBMessageProps } from './CBMessage.vue'
|
|
3
3
|
|
|
4
|
-
export {
|
|
5
|
-
CBMessage,
|
|
6
|
-
CBMessageProps
|
|
7
|
-
}
|
|
4
|
+
export { CBMessage, CBMessageProps }
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export type ChatBotMessage = {
|
|
2
|
-
id: number
|
|
3
|
-
message: string
|
|
4
|
-
date: Date
|
|
2
|
+
id: number
|
|
3
|
+
message: string
|
|
4
|
+
date: Date
|
|
5
5
|
sender: 'bot' | 'user'
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export type ChatBotMessageContent = {
|
|
9
|
-
content: string
|
|
9
|
+
content: string
|
|
10
10
|
type: string
|
|
11
|
-
}
|
|
11
|
+
}
|
package/src/types/texts.type.ts
CHANGED