@quidgest/chatbot 0.5.0 → 0.5.3-dev.0
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 +1 -2
- package/dist/components/ChatBot/ChatBot.vue.d.ts +2 -0
- package/dist/components/ChatBot/types.d.ts +2 -1
- package/dist/components/ChatBotInput/ChatBotInput.vue.d.ts +2 -2
- package/dist/components/ChatBotInput/__tests__/ChatBotInput.spec.d.ts +1 -0
- package/dist/components/ChatBotMessage/ChatBotMessage.vue.d.ts +3 -1
- package/dist/components/ChatBotMessage/__tests__/ChatBotMessageButtons.spec.d.ts +1 -0
- package/dist/components/ChatToolBar/__tests__/ChatToolBar.spec.d.ts +1 -0
- package/dist/components/FieldPreview/FieldPreview.vue.d.ts +2 -0
- package/dist/components/FieldPreview/__tests__/FieldPreview.spec.d.ts +1 -0
- package/dist/components/MarkdownRender/__tests__/MarkdownRender.spec.d.ts +1 -0
- package/dist/components/PulseDots/__tests__/PulseDots.spec.d.ts +1 -0
- package/dist/composables/__tests__/useChatMessages.spec.d.ts +1 -0
- package/dist/composables/__tests__/useSSE.spec.d.ts +1 -0
- package/dist/composables/useChatApi.d.ts +1 -1
- package/dist/composables/useChatMessages.d.ts +2 -1
- package/dist/composables/useSSE.d.ts +1 -2
- package/dist/composables/useTexts.d.ts +5 -0
- package/dist/index.js +25 -25
- package/dist/index.mjs +2317 -1810
- package/dist/style.css +1 -1
- package/dist/test/setup.d.ts +1 -0
- package/dist/utils/__tests__/parseFieldValue.spec.d.ts +1 -0
- package/package.json +28 -7
- package/src/assets/styles/styles.scss +212 -220
- package/src/components/ChatBot/ChatBot.vue +346 -370
- package/src/components/ChatBot/types.ts +34 -33
- package/src/components/ChatBotInput/ChatBotInput.vue +181 -190
- package/src/components/ChatBotInput/__tests__/ChatBotInput.spec.ts +292 -0
- package/src/components/ChatBotInput/__tests__/__snapshots__/ChatBotInput.spec.ts.snap +25 -0
- package/src/components/ChatBotInput/types.ts +24 -24
- package/src/components/ChatBotMessage/ChatBotMessage.vue +133 -134
- package/src/components/ChatBotMessage/ChatBotMessageButtons.vue +179 -164
- package/src/components/ChatBotMessage/__tests__/ChatBotMessageButtons.spec.ts +199 -0
- package/src/components/ChatBotMessage/__tests__/__snapshots__/ChatBotMessageButtons.spec.ts.snap +25 -0
- package/src/components/ChatBotMessage/types.ts +52 -52
- package/src/components/ChatToolBar/ChatToolBar.vue +69 -64
- package/src/components/ChatToolBar/__tests__/ChatToolBar.spec.ts +138 -0
- package/src/components/ChatToolBar/__tests__/__snapshots__/ChatToolBar.spec.ts.snap +11 -0
- package/src/components/ChatToolBar/types.ts +12 -12
- package/src/components/FieldPreview/FieldPreview.vue +83 -63
- package/src/components/FieldPreview/__tests__/FieldPreview.spec.ts +72 -0
- package/src/components/FieldPreview/__tests__/__snapshots__/FieldPreview.spec.ts.snap +19 -0
- package/src/components/FieldPreview/field-preview.scss +28 -24
- package/src/components/FieldPreview/types.ts +5 -5
- package/src/components/MarkdownRender/MarkdownRender.vue +16 -15
- package/src/components/MarkdownRender/__tests__/MarkdownRender.spec.ts +68 -0
- package/src/components/MarkdownRender/__tests__/__snapshots__/MarkdownRender.spec.ts.snap +8 -0
- package/src/components/MarkdownRender/markdown-render.scss +19 -20
- package/src/components/MarkdownRender/types.ts +3 -3
- package/src/components/PulseDots/PulseDots.vue +17 -17
- package/src/components/PulseDots/__tests__/PulseDots.spec.ts +35 -0
- package/src/components/PulseDots/__tests__/__snapshots__/PulseDots.spec.ts.snap +7 -0
- package/src/components/PulseDots/__tests__/__snapshots__/pulse-dots.spec.ts.snap +7 -0
- package/src/components/PulseDots/pulse-dots.scss +24 -23
- package/src/composables/__tests__/useChatMessages.spec.ts +64 -0
- package/src/composables/__tests__/useSSE.spec.ts +132 -0
- package/src/composables/useChatApi.ts +132 -134
- package/src/composables/useChatMessages.ts +50 -48
- package/src/composables/useSSE.ts +75 -73
- package/src/composables/useTexts.ts +33 -30
- package/src/test/setup.ts +41 -0
- package/src/utils/__tests__/parseFieldValue.spec.ts +27 -0
- package/src/utils/parseFieldValue.ts +12 -0
- package/src/utils/helper.ts +0 -12
- /package/dist/utils/{helper.d.ts → parseFieldValue.d.ts} +0 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// Composables
|
|
2
|
+
import { useSSE } from '../useSSE'
|
|
3
|
+
|
|
4
|
+
// Utils
|
|
5
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
6
|
+
import axios from 'axios'
|
|
7
|
+
|
|
8
|
+
// Types
|
|
9
|
+
import type { SSEvents } from '../useSSE'
|
|
10
|
+
|
|
11
|
+
// Mocks
|
|
12
|
+
vi.mock('axios')
|
|
13
|
+
const mockedAxios = vi.mocked(axios)
|
|
14
|
+
|
|
15
|
+
// Utility to create a mock ReadableStream
|
|
16
|
+
function createMockStream(chunks: string[]) {
|
|
17
|
+
return new ReadableStream({
|
|
18
|
+
start(controller) {
|
|
19
|
+
for (const chunk of chunks) {
|
|
20
|
+
controller.enqueue(new TextEncoder().encode(chunk))
|
|
21
|
+
}
|
|
22
|
+
controller.close()
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
describe('useSSE', () => {
|
|
28
|
+
let handlers: SSEvents = {}
|
|
29
|
+
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
vi.clearAllMocks()
|
|
32
|
+
handlers = {
|
|
33
|
+
onMessage: vi.fn(),
|
|
34
|
+
onError: vi.fn(),
|
|
35
|
+
onFieldMetadata: vi.fn(),
|
|
36
|
+
onDone: vi.fn()
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('should handle a message event', async () => {
|
|
41
|
+
const stream = createMockStream(['event: message\ndata: {"value":"hello"}\n\n'])
|
|
42
|
+
mockedAxios.mockResolvedValue({ data: stream })
|
|
43
|
+
|
|
44
|
+
await useSSE({ url: '/sse' }, handlers)
|
|
45
|
+
|
|
46
|
+
expect(handlers.onMessage).toHaveBeenCalledWith('hello')
|
|
47
|
+
expect(handlers.onDone).toHaveBeenCalled()
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it('should handle an error event', async () => {
|
|
51
|
+
const stream = createMockStream([
|
|
52
|
+
'event: error\ndata: {"value":"Something went wrong"}\n\n'
|
|
53
|
+
])
|
|
54
|
+
mockedAxios.mockResolvedValue({ data: stream })
|
|
55
|
+
|
|
56
|
+
await useSSE({ url: '/sse' }, handlers)
|
|
57
|
+
|
|
58
|
+
expect(handlers.onError).toHaveBeenCalled()
|
|
59
|
+
|
|
60
|
+
// We need to cast to access the mock calls
|
|
61
|
+
const onErrorHandler = handlers.onError as ReturnType<typeof vi.fn>
|
|
62
|
+
const errorArg = onErrorHandler.mock.calls[0][0]
|
|
63
|
+
|
|
64
|
+
expect(errorArg).toBeInstanceOf(Error)
|
|
65
|
+
expect(errorArg.message).toBe('Something went wrong')
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('should handle field metadata event', async () => {
|
|
69
|
+
const metadata = { foo: 'bar' }
|
|
70
|
+
const stream = createMockStream([
|
|
71
|
+
`event: field_metadata\ndata: ${JSON.stringify(metadata)}\n\n`
|
|
72
|
+
])
|
|
73
|
+
mockedAxios.mockResolvedValue({ data: stream })
|
|
74
|
+
await useSSE({ url: '/sse' }, handlers)
|
|
75
|
+
|
|
76
|
+
expect(handlers.onFieldMetadata).toHaveBeenCalledWith(metadata)
|
|
77
|
+
expect(handlers.onDone).toHaveBeenCalled()
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('should handle a done event', async () => {
|
|
81
|
+
const stream = createMockStream(['event: done\ndata: {}\n\n'])
|
|
82
|
+
mockedAxios.mockResolvedValue({ data: stream })
|
|
83
|
+
|
|
84
|
+
await useSSE({ url: '/sse' }, handlers)
|
|
85
|
+
|
|
86
|
+
expect(handlers.onDone).toHaveBeenCalled()
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('should call onError on invalid JSON', async () => {
|
|
90
|
+
const stream = createMockStream(['event: message\ndata: {invalid json}\n\n'])
|
|
91
|
+
mockedAxios.mockResolvedValue({ data: stream })
|
|
92
|
+
|
|
93
|
+
// Suppress console.error for this test
|
|
94
|
+
const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
|
|
95
|
+
|
|
96
|
+
await useSSE({ url: '/sse' }, handlers)
|
|
97
|
+
|
|
98
|
+
expect(handlers.onError).toHaveBeenCalled()
|
|
99
|
+
const onErrorHandler = handlers.onError as ReturnType<typeof vi.fn>
|
|
100
|
+
const errorArg = onErrorHandler.mock.calls[0][0]
|
|
101
|
+
|
|
102
|
+
expect(errorArg).toBeInstanceOf(Error)
|
|
103
|
+
consoleErrorSpy.mockRestore()
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
it('should default to message event if name is missing', async () => {
|
|
107
|
+
const stream = createMockStream(['data: {"value":"default event"}\n\n'])
|
|
108
|
+
mockedAxios.mockResolvedValue({ data: stream })
|
|
109
|
+
|
|
110
|
+
await useSSE({ url: '/sse' }, handlers)
|
|
111
|
+
|
|
112
|
+
expect(handlers.onMessage).toHaveBeenCalledWith('default event')
|
|
113
|
+
expect(handlers.onDone).toHaveBeenCalled()
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('should throw an error for non-stream response', async () => {
|
|
117
|
+
mockedAxios.mockResolvedValue({ data: null })
|
|
118
|
+
const fn = useSSE({ url: '/sse' }, handlers)
|
|
119
|
+
await expect(fn).rejects.toThrow('Invalid stream response')
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
it('should warn on unknown event type', async () => {
|
|
123
|
+
const stream = createMockStream(['event: unknown_event\ndata: {"value":"something"}\n\n'])
|
|
124
|
+
mockedAxios.mockResolvedValue({ data: stream })
|
|
125
|
+
|
|
126
|
+
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
|
|
127
|
+
await useSSE({ url: '/sse' }, handlers)
|
|
128
|
+
|
|
129
|
+
expect(consoleWarnSpy).toHaveBeenCalledWith('Unknown event type: unknown_event')
|
|
130
|
+
consoleWarnSpy.mockRestore()
|
|
131
|
+
})
|
|
132
|
+
})
|
|
@@ -8,149 +8,147 @@ import { ChatBotMessageContent } from '@/components/ChatBot/types'
|
|
|
8
8
|
import { useSSE } from './useSSE'
|
|
9
9
|
|
|
10
10
|
type RequestResponse<T> = {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
data: T | null
|
|
12
|
+
error: Error | null
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export function useChatApi(apiEndpoint: string) {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
const isLoading = ref(false)
|
|
17
|
+
const lastError = ref<Error | null>(null)
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
isLoading.value = true
|
|
23
|
-
lastError.value = null
|
|
19
|
+
async function baseRequest<T>(config: AxiosRequestConfig): Promise<RequestResponse<T>> {
|
|
20
|
+
isLoading.value = true
|
|
21
|
+
lastError.value = null
|
|
24
22
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
23
|
+
try {
|
|
24
|
+
const response: AxiosResponse<T> = await axios({
|
|
25
|
+
...config,
|
|
26
|
+
baseURL: apiEndpoint
|
|
27
|
+
})
|
|
28
|
+
return { data: response.data, error: null }
|
|
29
|
+
} catch (error: unknown) {
|
|
30
|
+
if (error instanceof Error) {
|
|
31
|
+
lastError.value = error
|
|
32
|
+
console.error('Error in API request:', error)
|
|
33
|
+
return { data: null, error }
|
|
34
|
+
}
|
|
35
|
+
} finally {
|
|
36
|
+
isLoading.value = false
|
|
37
|
+
}
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
agentID: string,
|
|
44
|
-
formId: string
|
|
45
|
-
) {
|
|
46
|
-
return await baseRequest<{
|
|
47
|
-
success: boolean
|
|
48
|
-
history: ChatBotMessageContent[]
|
|
49
|
-
}>({
|
|
50
|
-
method: 'POST',
|
|
51
|
-
url: `/prompt/load`,
|
|
52
|
-
data: {
|
|
53
|
-
username,
|
|
54
|
-
project,
|
|
55
|
-
agentID,
|
|
56
|
-
formId
|
|
57
|
-
}
|
|
58
|
-
})
|
|
59
|
-
}
|
|
39
|
+
// This should never be reached, but TypeScript needs it
|
|
40
|
+
return { data: null, error: new Error('Unknown error occurred in baseRequest') }
|
|
41
|
+
}
|
|
60
42
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
})
|
|
77
|
-
}
|
|
43
|
+
async function getChatData(username: string, project: string, agentID: string, formId: string) {
|
|
44
|
+
return await baseRequest<{
|
|
45
|
+
success: boolean
|
|
46
|
+
history: ChatBotMessageContent[]
|
|
47
|
+
}>({
|
|
48
|
+
method: 'POST',
|
|
49
|
+
url: `/prompt/load`,
|
|
50
|
+
data: {
|
|
51
|
+
username,
|
|
52
|
+
project,
|
|
53
|
+
agentID,
|
|
54
|
+
formId
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
}
|
|
78
58
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
59
|
+
async function sendPrompt(
|
|
60
|
+
formData: FormData,
|
|
61
|
+
onChunk: (chunk: string) => void,
|
|
62
|
+
onError?: (error: Error) => void
|
|
63
|
+
) {
|
|
64
|
+
isLoading.value = true
|
|
65
|
+
try {
|
|
66
|
+
return await useSSE(
|
|
67
|
+
{
|
|
68
|
+
method: 'POST',
|
|
69
|
+
url: `${apiEndpoint}/prompt/submit`,
|
|
70
|
+
data: formData
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
onMessage: (data) => {
|
|
74
|
+
onChunk(data)
|
|
75
|
+
},
|
|
76
|
+
onDone: () => (isLoading.value = false)
|
|
77
|
+
}
|
|
78
|
+
)
|
|
79
|
+
} catch (error) {
|
|
80
|
+
isLoading.value = false
|
|
81
|
+
onError?.(error as Error)
|
|
82
|
+
console.error('Error in sendPrompt:', error)
|
|
83
|
+
throw error
|
|
84
|
+
}
|
|
85
|
+
}
|
|
104
86
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
87
|
+
async function getJobResultData(
|
|
88
|
+
jobId: string,
|
|
89
|
+
onChunk: (chunk: string) => void,
|
|
90
|
+
onMetaData: (metadata: Record<string, unknown>) => void,
|
|
91
|
+
onRequestError?: (error: Error) => void
|
|
92
|
+
) {
|
|
93
|
+
isLoading.value = true
|
|
94
|
+
try {
|
|
95
|
+
return await useSSE(
|
|
96
|
+
{
|
|
97
|
+
method: 'POST',
|
|
98
|
+
url: `${apiEndpoint}/get-job-result`,
|
|
99
|
+
data: {
|
|
100
|
+
jobId
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
onMessage: (data) => onChunk(data),
|
|
105
|
+
onFieldMetadata: (metadata) => onMetaData(metadata),
|
|
106
|
+
onDone: () => (isLoading.value = false)
|
|
107
|
+
}
|
|
108
|
+
)
|
|
109
|
+
} catch (error) {
|
|
110
|
+
lastError.value = error as Error
|
|
111
|
+
onRequestError?.(error as Error)
|
|
112
|
+
isLoading.value = false
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async function clearChatData(
|
|
116
|
+
username: string,
|
|
117
|
+
project: string,
|
|
118
|
+
agentID: string,
|
|
119
|
+
formId: string
|
|
120
|
+
) {
|
|
121
|
+
return await baseRequest<{ success: boolean }>({
|
|
122
|
+
method: 'POST',
|
|
123
|
+
url: `/prompt/clear`,
|
|
124
|
+
data: {
|
|
125
|
+
username,
|
|
126
|
+
project,
|
|
127
|
+
agentID,
|
|
128
|
+
formId
|
|
129
|
+
}
|
|
130
|
+
})
|
|
131
|
+
}
|
|
130
132
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
feedbackComment: comment
|
|
143
|
-
}
|
|
144
|
-
})
|
|
145
|
-
}
|
|
133
|
+
async function handleFeedback(feedback: number, comment: string, sessionID: string) {
|
|
134
|
+
return await baseRequest<{ success: boolean }>({
|
|
135
|
+
method: 'POST',
|
|
136
|
+
url: `/prompt/feedback`,
|
|
137
|
+
data: {
|
|
138
|
+
messageSessionID: sessionID,
|
|
139
|
+
feedbackValue: feedback,
|
|
140
|
+
feedbackComment: comment
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
}
|
|
146
144
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
145
|
+
return {
|
|
146
|
+
isLoading,
|
|
147
|
+
lastError,
|
|
148
|
+
getChatData,
|
|
149
|
+
clearChatData,
|
|
150
|
+
getJobResultData,
|
|
151
|
+
sendPrompt,
|
|
152
|
+
handleFeedback
|
|
153
|
+
}
|
|
156
154
|
}
|
|
@@ -2,57 +2,59 @@ import { ref } from 'vue'
|
|
|
2
2
|
import { v4 as uuidv4 } from 'uuid'
|
|
3
3
|
|
|
4
4
|
import type { Ref } from 'vue'
|
|
5
|
-
import type {
|
|
6
|
-
ChatMessage,
|
|
7
|
-
ChatBotMessageSender
|
|
8
|
-
} from '@/components/ChatBot/types'
|
|
5
|
+
import type { ChatMessage, ChatBotMessageSender } from '@/components/ChatBot/types'
|
|
9
6
|
|
|
10
7
|
const messages: Ref<ChatMessage[]> = ref([])
|
|
11
8
|
const nextMessageId = ref(1)
|
|
12
9
|
|
|
13
10
|
export function useChatMessages() {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
11
|
+
function addChatMessage(
|
|
12
|
+
message: string,
|
|
13
|
+
sender?: ChatBotMessageSender,
|
|
14
|
+
imagePreviewUrl?: string | null,
|
|
15
|
+
sessionID?: string,
|
|
16
|
+
isWelcomeMessage?: boolean
|
|
17
|
+
) {
|
|
18
|
+
const newMessage: ChatMessage = {
|
|
19
|
+
id: nextMessageId.value++,
|
|
20
|
+
message,
|
|
21
|
+
date: new Date(),
|
|
22
|
+
sender: sender || 'bot',
|
|
23
|
+
sessionID: sessionID || uuidv4(),
|
|
24
|
+
imagePreviewUrl: imagePreviewUrl || undefined,
|
|
25
|
+
isWelcomeMessage,
|
|
26
|
+
fields: []
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
messages.value.push(newMessage)
|
|
30
|
+
|
|
31
|
+
return newMessage
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function getLastMessage() {
|
|
35
|
+
return messages.value.find((m: ChatMessage) => m.id === nextMessageId.value - 1)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function clearMessages() {
|
|
39
|
+
messages.value = []
|
|
40
|
+
nextMessageId.value = 1
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function deleteMessageById(messageId: number) {
|
|
44
|
+
messages.value = messages.value.filter((m) => m.id !== messageId)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function getMessages() {
|
|
48
|
+
return messages.value
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
messages,
|
|
53
|
+
nextMessageId,
|
|
54
|
+
addChatMessage,
|
|
55
|
+
getLastMessage,
|
|
56
|
+
clearMessages,
|
|
57
|
+
getMessages,
|
|
58
|
+
deleteMessageById
|
|
59
|
+
}
|
|
58
60
|
}
|