@quidgest/chatbot 0.0.6 → 0.0.8
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 +4 -4
- package/dist/components/ChatBot.vue.d.ts +8 -7
- package/dist/components/index.d.ts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +9 -3066
- package/dist/index.mjs +1925 -2377
- package/dist/style.css +1 -93
- package/package.json +13 -9
- package/src/assets/styles/styles.scss +55 -11
- package/src/components/CBMessage.vue +4 -5
- package/src/components/ChatBot.vue +130 -165
- 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
|
+
useTemplateRef,
|
|
5
|
+
nextTick,
|
|
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,31 @@
|
|
|
7
14
|
|
|
8
15
|
import {
|
|
9
16
|
QButton,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
17
|
+
QTextArea,
|
|
18
|
+
QIcon,
|
|
19
|
+
QLabel
|
|
13
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
|
-
let msgHistoryStack: string[] = []
|
|
21
29
|
let nextMessageId: number = 1
|
|
22
30
|
let userPrompt: Ref<string> = ref('')
|
|
23
31
|
let isLoading: Ref<boolean> = ref(false)
|
|
24
32
|
let isChatDisabled: boolean = false
|
|
25
|
-
|
|
33
|
+
|
|
26
34
|
// refs
|
|
27
|
-
const scrollElement =
|
|
28
|
-
const promptInput = ref<HTMLInputElement | null>(null)
|
|
35
|
+
const scrollElement = useTemplateRef('scrollElement')
|
|
29
36
|
|
|
30
37
|
export type ChatBotProps = {
|
|
31
38
|
/**
|
|
32
39
|
* API Enpoint URL
|
|
33
40
|
*/
|
|
34
|
-
apiEndpoint?: string
|
|
41
|
+
apiEndpoint?: string
|
|
35
42
|
|
|
36
43
|
/**
|
|
37
44
|
* Static resource texts used by ChatBot
|
|
@@ -59,7 +66,7 @@
|
|
|
59
66
|
texts: () => ({
|
|
60
67
|
chatbotTitle: 'ChatBot',
|
|
61
68
|
qButtonTitle: 'Send message',
|
|
62
|
-
|
|
69
|
+
inputLabel: 'What can I help with?',
|
|
63
70
|
initialMessage:
|
|
64
71
|
"Howdy! I am GenioBot 👋, Quidgest's personal AI assistant! How can I help you?",
|
|
65
72
|
loginError:
|
|
@@ -73,38 +80,34 @@
|
|
|
73
80
|
initChat()
|
|
74
81
|
})
|
|
75
82
|
|
|
76
|
-
const userMessages = computed(() => {
|
|
77
|
-
return messages.value.filter((m: ChatBotMessage) => m.sender === 'user')
|
|
78
|
-
})
|
|
79
|
-
|
|
80
83
|
function setDisabledState(state: boolean) {
|
|
81
84
|
isChatDisabled = state
|
|
82
85
|
}
|
|
83
|
-
|
|
86
|
+
|
|
84
87
|
function initChat() {
|
|
85
88
|
Axios.post(props.apiEndpoint + '/auth/login', {
|
|
86
89
|
username: props.username,
|
|
87
90
|
password: 'test'
|
|
88
91
|
})
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
.then((response: AxiosResponse) => {
|
|
93
|
+
if (response.status != 200 || !response.data.success) {
|
|
94
|
+
setDisabledState(true)
|
|
95
|
+
addChatMessage(props.texts.loginError)
|
|
96
|
+
return console.log(
|
|
97
|
+
`Unsuccessful login, endpoint gave status ${response.status}`
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
loadChatData()
|
|
102
|
+
})
|
|
103
|
+
.catch((error: Error) => {
|
|
91
104
|
setDisabledState(true)
|
|
92
105
|
addChatMessage(props.texts.loginError)
|
|
93
|
-
|
|
94
|
-
|
|
106
|
+
console.log(
|
|
107
|
+
'The following error ocurred while trying to login: \n' +
|
|
108
|
+
error
|
|
95
109
|
)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
loadChatData()
|
|
99
|
-
})
|
|
100
|
-
.catch((error: Error) => {
|
|
101
|
-
setDisabledState(true)
|
|
102
|
-
addChatMessage(props.texts.loginError)
|
|
103
|
-
console.log(
|
|
104
|
-
'The following error ocurred while trying to login: \n' +
|
|
105
|
-
error
|
|
106
|
-
)
|
|
107
|
-
})
|
|
110
|
+
})
|
|
108
111
|
}
|
|
109
112
|
|
|
110
113
|
function loadChatData() {
|
|
@@ -112,28 +115,33 @@
|
|
|
112
115
|
username: props.username,
|
|
113
116
|
project: props.projectPath
|
|
114
117
|
})
|
|
115
|
-
|
|
116
|
-
|
|
118
|
+
.then((response: AxiosResponse) => {
|
|
119
|
+
if (response.status != 200 || !response.data.success) {
|
|
120
|
+
setDisabledState(true)
|
|
121
|
+
addChatMessage(props.texts.loginError)
|
|
122
|
+
return console.log(
|
|
123
|
+
`Unsuccessful load, endpoint gave status ${response.status}`
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
sendInitialMessage()
|
|
128
|
+
response.data.history.forEach(
|
|
129
|
+
(message: ChatBotMessageContent) => {
|
|
130
|
+
addChatMessage(
|
|
131
|
+
message.content,
|
|
132
|
+
message.type === 'ai' ? 'bot' : 'user'
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
)
|
|
136
|
+
})
|
|
137
|
+
.catch((error: Error) => {
|
|
117
138
|
setDisabledState(true)
|
|
118
139
|
addChatMessage(props.texts.loginError)
|
|
119
|
-
|
|
120
|
-
|
|
140
|
+
console.log(
|
|
141
|
+
'The following error ocurred while trying to login: \n' +
|
|
142
|
+
error
|
|
121
143
|
)
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
sendInitialMessage()
|
|
125
|
-
response.data.history.forEach((message: ChatBotMessageContent) => {
|
|
126
|
-
addChatMessage(message.content, message.type === "ai" ? "bot" : "user")
|
|
127
144
|
})
|
|
128
|
-
})
|
|
129
|
-
.catch((error: Error) => {
|
|
130
|
-
setDisabledState(true)
|
|
131
|
-
addChatMessage(props.texts.loginError)
|
|
132
|
-
console.log(
|
|
133
|
-
'The following error ocurred while trying to login: \n' +
|
|
134
|
-
error
|
|
135
|
-
)
|
|
136
|
-
})
|
|
137
145
|
}
|
|
138
146
|
|
|
139
147
|
function addChatMessage(message: string, sender: 'bot' | 'user' = 'bot') {
|
|
@@ -159,58 +167,15 @@
|
|
|
159
167
|
|
|
160
168
|
function resetChat() {
|
|
161
169
|
messages.value = []
|
|
162
|
-
msgHistoryStack = []
|
|
163
170
|
userPrompt.value = ''
|
|
164
171
|
isLoading.value = false
|
|
165
172
|
setDisabledState(false)
|
|
166
173
|
}
|
|
167
174
|
|
|
168
175
|
function scrollToBottom() {
|
|
169
|
-
|
|
176
|
+
scrollElement.value?.scrollIntoView({ behavior: 'smooth' })
|
|
170
177
|
}
|
|
171
178
|
|
|
172
|
-
function handleKey(event: KeyboardEvent) {
|
|
173
|
-
if(promptInput.value == null) return;
|
|
174
|
-
|
|
175
|
-
if (event.key == 'ArrowUp') {
|
|
176
|
-
//No user messages, no need to continue
|
|
177
|
-
if (userMessages.value.length == 0) return
|
|
178
|
-
|
|
179
|
-
//Get next message to read
|
|
180
|
-
let lastMsgObj =
|
|
181
|
-
userMessages.value[
|
|
182
|
-
userMessages.value.length -
|
|
183
|
-
1 -
|
|
184
|
-
msgHistoryStack.length
|
|
185
|
-
]
|
|
186
|
-
|
|
187
|
-
//No more messages to go through
|
|
188
|
-
if (!lastMsgObj) return
|
|
189
|
-
|
|
190
|
-
//Save current prompt (even if modified) & update input
|
|
191
|
-
msgHistoryStack.push(userPrompt.value)
|
|
192
|
-
userPrompt.value = lastMsgObj.message
|
|
193
|
-
|
|
194
|
-
//Set the cursor to the end of text
|
|
195
|
-
nextTick(() =>
|
|
196
|
-
setCursorPosition(
|
|
197
|
-
promptInput.value as HTMLInputElement,
|
|
198
|
-
lastMsgObj.message.length
|
|
199
|
-
)
|
|
200
|
-
)
|
|
201
|
-
} else if (event.key == 'ArrowDown') {
|
|
202
|
-
let previousHistoryText = msgHistoryStack.pop()
|
|
203
|
-
|
|
204
|
-
if (!previousHistoryText) {
|
|
205
|
-
//No more prompts in the stack
|
|
206
|
-
userPrompt.value = ''
|
|
207
|
-
return
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
userPrompt.value = previousHistoryText
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
179
|
function sendMessage() {
|
|
215
180
|
if (
|
|
216
181
|
userPrompt.value.trim().length == 0 ||
|
|
@@ -243,8 +208,7 @@
|
|
|
243
208
|
method: 'POST',
|
|
244
209
|
data: params,
|
|
245
210
|
onDownloadProgress: (progressEvent) => {
|
|
246
|
-
const chunk =
|
|
247
|
-
progressEvent.event?.currentTarget.response
|
|
211
|
+
const chunk = progressEvent.event?.currentTarget.response
|
|
248
212
|
const status = progressEvent.event?.currentTarget.status
|
|
249
213
|
|
|
250
214
|
if (status != 200) return
|
|
@@ -253,74 +217,69 @@
|
|
|
253
217
|
scrollToBottom()
|
|
254
218
|
}
|
|
255
219
|
})
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
setDisabledState(true)
|
|
263
|
-
console.log(error)
|
|
264
|
-
})
|
|
265
|
-
.finally(() => {
|
|
266
|
-
isLoading.value = false
|
|
267
|
-
})
|
|
268
|
-
}
|
|
220
|
+
.then(({ data }) => {
|
|
221
|
+
if (msg) msg.message = data
|
|
222
|
+
})
|
|
223
|
+
.catch((error) => {
|
|
224
|
+
addChatMessage(props.texts.botIsSick)
|
|
269
225
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
226
|
+
setDisabledState(true)
|
|
227
|
+
console.log(error)
|
|
228
|
+
})
|
|
229
|
+
.finally(() => {
|
|
230
|
+
isLoading.value = false
|
|
231
|
+
})
|
|
273
232
|
}
|
|
274
233
|
|
|
275
|
-
function clearChat() {
|
|
234
|
+
function clearChat() {
|
|
276
235
|
Axios.post(props.apiEndpoint + '/prompt/clear', {
|
|
277
236
|
username: props.username,
|
|
278
237
|
project: props.projectPath
|
|
279
238
|
})
|
|
280
|
-
|
|
281
|
-
|
|
239
|
+
.then((response: AxiosResponse) => {
|
|
240
|
+
if (response.status != 200 || !response.data.success) {
|
|
241
|
+
setDisabledState(true)
|
|
242
|
+
addChatMessage(props.texts.loginError)
|
|
243
|
+
return console.log(
|
|
244
|
+
`Unsuccessful login, endpoint gave status ${response.status}`
|
|
245
|
+
)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
resetChat()
|
|
249
|
+
sendInitialMessage()
|
|
250
|
+
})
|
|
251
|
+
.catch((error: Error) => {
|
|
282
252
|
setDisabledState(true)
|
|
283
253
|
addChatMessage(props.texts.loginError)
|
|
284
|
-
|
|
285
|
-
|
|
254
|
+
console.log(
|
|
255
|
+
'The following error ocurred while trying to communicate with the endpoint: \n' +
|
|
256
|
+
error
|
|
286
257
|
)
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
resetChat()
|
|
290
|
-
sendInitialMessage()
|
|
291
|
-
})
|
|
292
|
-
.catch((error: Error) => {
|
|
293
|
-
setDisabledState(true)
|
|
294
|
-
addChatMessage(props.texts.loginError)
|
|
295
|
-
console.log(
|
|
296
|
-
'The following error ocurred while trying to communicate with the endpoint: \n' +
|
|
297
|
-
error
|
|
298
|
-
)
|
|
299
|
-
})
|
|
258
|
+
})
|
|
300
259
|
}
|
|
301
260
|
|
|
302
261
|
function getMessageClasses(sender: 'user' | 'bot') {
|
|
303
262
|
const classes: string[] = ['q-chatbot__messages-wrapper']
|
|
304
263
|
|
|
305
|
-
if(sender == 'user')
|
|
306
|
-
classes.push('q-chatbot__messages-wrapper_right')
|
|
264
|
+
if (sender == 'user') classes.push('q-chatbot__messages-wrapper_right')
|
|
307
265
|
|
|
308
266
|
return classes
|
|
309
267
|
}
|
|
310
268
|
|
|
311
|
-
watch(
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
269
|
+
watch(
|
|
270
|
+
() => props.apiEndpoint,
|
|
271
|
+
() => {
|
|
272
|
+
resetChat()
|
|
273
|
+
initChat()
|
|
274
|
+
}
|
|
275
|
+
)
|
|
315
276
|
|
|
316
277
|
defineOptions({ name: 'ChatBot' })
|
|
317
278
|
</script>
|
|
318
279
|
|
|
319
280
|
<template>
|
|
320
281
|
<div class="q-chatbot">
|
|
321
|
-
<div
|
|
322
|
-
class="q-chatbot__content">
|
|
323
|
-
|
|
282
|
+
<div class="q-chatbot__content">
|
|
324
283
|
<!-- Chat tools -->
|
|
325
284
|
<div class="q-chatbot__tools">
|
|
326
285
|
<QButton
|
|
@@ -338,36 +297,42 @@
|
|
|
338
297
|
v-for="message in messages"
|
|
339
298
|
:key="message.id"
|
|
340
299
|
:class="getMessageClasses(message.sender)">
|
|
341
|
-
<CBMessage
|
|
300
|
+
<CBMessage
|
|
301
|
+
v-bind="message"
|
|
302
|
+
:date-format="props.dateFormat"
|
|
303
|
+
:loading="isLoading && !message.message" />
|
|
342
304
|
</div>
|
|
343
305
|
</div>
|
|
344
306
|
|
|
345
307
|
<div ref="scrollElement"></div>
|
|
308
|
+
|
|
309
|
+
<div class="q-chatbot__footer-container">
|
|
310
|
+
<label> {{ props.texts.inputLabel }} </label>
|
|
311
|
+
<div class="q-chatbot__footer">
|
|
312
|
+
<div class="q-chatbot__input">
|
|
313
|
+
<QTextArea
|
|
314
|
+
v-model="userPrompt"
|
|
315
|
+
size="block"
|
|
316
|
+
autosize
|
|
317
|
+
resize="none"
|
|
318
|
+
:rows="2"
|
|
319
|
+
:disabled="isChatDisabled"
|
|
320
|
+
@keyup.enter="sendMessage" />
|
|
321
|
+
</div>
|
|
322
|
+
<div class="q-chatbot__send-container">
|
|
323
|
+
<QButton
|
|
324
|
+
:title="props.texts.qButtonTitle"
|
|
325
|
+
b-style="primary"
|
|
326
|
+
class="q-chatbot__send"
|
|
327
|
+
:disabled="isChatDisabled || isLoading"
|
|
328
|
+
:loading="isLoading"
|
|
329
|
+
@click="sendMessage">
|
|
330
|
+
<QIcon icon="send" />
|
|
331
|
+
</QButton>
|
|
332
|
+
</div>
|
|
333
|
+
</div>
|
|
334
|
+
</div>
|
|
346
335
|
</div>
|
|
347
336
|
|
|
348
|
-
<QInputGroup
|
|
349
|
-
size="block"
|
|
350
|
-
:disabled="isChatDisabled">
|
|
351
|
-
<QTextField
|
|
352
|
-
ref="promptInput"
|
|
353
|
-
v-model="userPrompt"
|
|
354
|
-
class="q-chatbot__input"
|
|
355
|
-
:placeholder="props.texts.placeholderMessage"
|
|
356
|
-
:disabled="isChatDisabled"
|
|
357
|
-
@keyup.enter="sendMessage"
|
|
358
|
-
@keydown="handleKey" />
|
|
359
|
-
|
|
360
|
-
<template #append>
|
|
361
|
-
<QButton
|
|
362
|
-
:title="props.texts.qButtonTitle"
|
|
363
|
-
b-style="primary"
|
|
364
|
-
class="q-chatbot__send"
|
|
365
|
-
:disabled="isChatDisabled || isLoading"
|
|
366
|
-
:loading="isLoading"
|
|
367
|
-
@click="sendMessage">
|
|
368
|
-
<QIcon icon="send" />
|
|
369
|
-
</QButton>
|
|
370
|
-
</template>
|
|
371
|
-
</QInputGroup>
|
|
372
337
|
</div>
|
|
373
338
|
</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