@5minds/node-red-dashboard-2-processcube-chat 0.1.1-add-functionality-043ee8-mdy8o5ki → 0.1.1-develop-bd0cb7-mcvkuzxr
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/nodes/ui-deepchat.html +102 -87
- package/nodes/ui-deepchat.js +126 -13
- package/package.json +1 -2
- package/resources/ui-deepchat.umd.js +2 -273
- package/ui/components/UIDeepChat.vue +297 -317
- package/resources/ui-deepchat.umd.js.map +0 -1
|
@@ -1,369 +1,349 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="
|
|
2
|
+
<div ref="deepChatContainer" class="ui-deepchat-container" :style="containerStyle">
|
|
3
3
|
<deep-chat
|
|
4
|
-
|
|
5
|
-
:
|
|
6
|
-
:
|
|
4
|
+
ref="deepChat"
|
|
5
|
+
:intro-message="config.introMessage"
|
|
6
|
+
:placeholder-text="config.placeholder"
|
|
7
|
+
:text-input="config.textInput"
|
|
8
|
+
:speech-to-text="speechToTextConfig"
|
|
9
|
+
:camera="cameraConfig"
|
|
10
|
+
:microphone="microphoneConfig"
|
|
11
|
+
:mixedFiles="attachmentsConfig"
|
|
12
|
+
:avatars="config.avatars"
|
|
13
|
+
:names="config.names"
|
|
14
|
+
:timestamps="config.timestamps"
|
|
15
|
+
:stream="config.stream"
|
|
7
16
|
:connect="connectConfig"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
:timestamps="props.timestamps"
|
|
14
|
-
:stream="props.stream"
|
|
17
|
+
@onNewMessage="handleNewMessage"
|
|
18
|
+
@onClearMessages="handleClearMessages"
|
|
19
|
+
@onComponentRender="handleComponentRender"
|
|
20
|
+
@onResponse="handleResponse"
|
|
21
|
+
@onError="handleError"
|
|
15
22
|
></deep-chat>
|
|
16
23
|
</div>
|
|
17
24
|
</template>
|
|
18
25
|
|
|
19
26
|
<script>
|
|
20
|
-
import 'deep-chat';
|
|
21
|
-
|
|
22
27
|
export default {
|
|
23
28
|
name: 'UIDeepChat',
|
|
24
29
|
props: ['id', 'props', 'state'],
|
|
25
|
-
|
|
30
|
+
|
|
26
31
|
data() {
|
|
27
32
|
return {
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
config: {
|
|
34
|
+
introMessage: 'Hello! How can I help you today?',
|
|
35
|
+
placeholder: 'Type a message...',
|
|
36
|
+
apiUrl: '',
|
|
37
|
+
apiKey: '',
|
|
38
|
+
model: 'gpt-3.5-turbo',
|
|
39
|
+
textInput: true,
|
|
40
|
+
speechToText: false,
|
|
41
|
+
camera: false,
|
|
42
|
+
microphone: false,
|
|
43
|
+
attachments: false,
|
|
44
|
+
avatars: true,
|
|
45
|
+
names: true,
|
|
46
|
+
timestamps: false,
|
|
47
|
+
stream: false
|
|
48
|
+
},
|
|
49
|
+
isDeepChatLoaded: false,
|
|
50
|
+
messages: []
|
|
51
|
+
}
|
|
30
52
|
},
|
|
31
|
-
|
|
53
|
+
|
|
32
54
|
computed: {
|
|
33
|
-
|
|
55
|
+
containerStyle() {
|
|
34
56
|
return {
|
|
35
57
|
width: '100%',
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
};
|
|
58
|
+
height: '100%',
|
|
59
|
+
minHeight: '400px'
|
|
60
|
+
}
|
|
40
61
|
},
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
};
|
|
62
|
+
|
|
63
|
+
speechToTextConfig() {
|
|
64
|
+
return this.config.speechToText ? {
|
|
65
|
+
button: true,
|
|
66
|
+
displayInterimResults: true
|
|
67
|
+
} : false
|
|
48
68
|
},
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return {
|
|
52
|
-
|
|
53
|
-
}
|
|
69
|
+
|
|
70
|
+
cameraConfig() {
|
|
71
|
+
return this.config.camera ? {
|
|
72
|
+
button: true
|
|
73
|
+
} : false
|
|
54
74
|
},
|
|
55
|
-
|
|
75
|
+
|
|
76
|
+
microphoneConfig() {
|
|
77
|
+
return this.config.microphone ? {
|
|
78
|
+
button: true,
|
|
79
|
+
audio: true
|
|
80
|
+
} : false
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
attachmentsConfig() {
|
|
84
|
+
return this.config.attachments ? {
|
|
85
|
+
button: true,
|
|
86
|
+
acceptedFormats: ".jpeg,.jpg,.png,.gif,.pdf,.txt,.doc,.docx"
|
|
87
|
+
} : false
|
|
88
|
+
},
|
|
89
|
+
|
|
56
90
|
connectConfig() {
|
|
91
|
+
if (this.config.apiUrl && this.config.apiKey) {
|
|
92
|
+
return {
|
|
93
|
+
url: this.config.apiUrl,
|
|
94
|
+
method: 'POST',
|
|
95
|
+
headers: {
|
|
96
|
+
'Authorization': `Bearer ${this.config.apiKey}`,
|
|
97
|
+
'Content-Type': 'application/json'
|
|
98
|
+
},
|
|
99
|
+
body: {
|
|
100
|
+
model: this.config.model,
|
|
101
|
+
max_tokens: 2000,
|
|
102
|
+
temperature: 0.7
|
|
103
|
+
},
|
|
104
|
+
stream: this.config.stream
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Custom Handler für Node-RED Integration
|
|
57
109
|
return {
|
|
58
|
-
handler: this.
|
|
59
|
-
|
|
60
|
-
|
|
110
|
+
handler: this.handleCustomConnection,
|
|
111
|
+
stream: this.config.stream
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
mounted() {
|
|
117
|
+
this.loadDeepChat()
|
|
118
|
+
this.setupSocketListeners()
|
|
119
|
+
this.applyConfiguration()
|
|
61
120
|
},
|
|
121
|
+
|
|
62
122
|
beforeUnmount() {
|
|
63
|
-
this
|
|
123
|
+
this.removeSocketListeners()
|
|
64
124
|
},
|
|
65
|
-
|
|
125
|
+
|
|
66
126
|
methods: {
|
|
67
|
-
async
|
|
127
|
+
async loadDeepChat() {
|
|
68
128
|
try {
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
newMessages.push(messageContent);
|
|
79
|
-
} catch (e) {
|
|
80
|
-
console.error('Error parsing message:', e);
|
|
81
|
-
}
|
|
82
|
-
} else if (key === 'files') {
|
|
83
|
-
files.push(value);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Process files if present
|
|
88
|
-
if (files.length > 0 && newMessages.length > 0) {
|
|
89
|
-
const lastMessage = newMessages[newMessages.length - 1];
|
|
90
|
-
lastMessage.files = await this.processFiles(files);
|
|
129
|
+
// Deep Chat von CDN laden
|
|
130
|
+
if (!window.DeepChat) {
|
|
131
|
+
const script = document.createElement('script')
|
|
132
|
+
script.src = 'https://unpkg.com/deep-chat@latest/dist/deepChat.bundle.js'
|
|
133
|
+
script.onload = () => {
|
|
134
|
+
this.isDeepChatLoaded = true
|
|
135
|
+
this.$nextTick(() => {
|
|
136
|
+
this.initializeDeepChat()
|
|
137
|
+
})
|
|
91
138
|
}
|
|
92
|
-
|
|
93
|
-
|
|
139
|
+
document.head.appendChild(script)
|
|
140
|
+
} else {
|
|
141
|
+
this.isDeepChatLoaded = true
|
|
142
|
+
this.$nextTick(() => {
|
|
143
|
+
this.initializeDeepChat()
|
|
144
|
+
})
|
|
94
145
|
}
|
|
95
|
-
|
|
96
|
-
// Add to conversation history
|
|
97
|
-
this.conversation.push(...newMessages);
|
|
98
|
-
|
|
99
|
-
// Send to Node-RED
|
|
100
|
-
const payload = this.formatForChatGPT(this.conversation);
|
|
101
|
-
this.sendToNodeRED(payload, signals);
|
|
102
146
|
} catch (error) {
|
|
103
|
-
console.error('Error
|
|
104
|
-
this.sendErrorResponse(signals, 'Sorry, there was an error processing your message.');
|
|
147
|
+
console.error('Error loading Deep Chat:', error)
|
|
105
148
|
}
|
|
106
149
|
},
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
return await this.processAudioFile(file);
|
|
118
|
-
} else {
|
|
119
|
-
// Handle other file types (PDFs, documents, etc.)
|
|
120
|
-
return await this.processDocumentFile(file);
|
|
121
|
-
}
|
|
122
|
-
})
|
|
123
|
-
);
|
|
124
|
-
} catch (error) {
|
|
125
|
-
console.error('Error processing files:', error);
|
|
126
|
-
return [];
|
|
150
|
+
|
|
151
|
+
initializeDeepChat() {
|
|
152
|
+
if (this.$refs.deepChat) {
|
|
153
|
+
// Deep Chat ist bereit
|
|
154
|
+
console.log('Deep Chat initialized for widget:', this.id)
|
|
155
|
+
|
|
156
|
+
// Intro Message senden falls konfiguriert
|
|
157
|
+
if (this.config.introMessage) {
|
|
158
|
+
this.addMessage(this.config.introMessage, 'ai')
|
|
159
|
+
}
|
|
127
160
|
}
|
|
128
161
|
},
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
162
|
+
|
|
163
|
+
setupSocketListeners() {
|
|
164
|
+
// Neue Nachricht von Node-RED empfangen
|
|
165
|
+
this.$socket.on('deepchat-newMessage:' + this.id, (data) => {
|
|
166
|
+
this.addMessage(data.message, data.role || 'ai', data.html, data.files)
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
// Konfiguration aktualisieren
|
|
170
|
+
this.$socket.on('deepchat-updateConfig:' + this.id, (newConfig) => {
|
|
171
|
+
this.config = { ...this.config, ...newConfig }
|
|
172
|
+
this.applyConfiguration()
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
// Chat löschen
|
|
176
|
+
this.$socket.on('deepchat-clearMessages:' + this.id, () => {
|
|
177
|
+
this.clearMessages()
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
// Standard Dashboard Message Input
|
|
181
|
+
this.$socket.on('msg-input:' + this.id, (msg) => {
|
|
182
|
+
if (msg.payload) {
|
|
183
|
+
this.addMessage(msg.payload, msg.role || 'ai', msg.html, msg.files)
|
|
184
|
+
}
|
|
185
|
+
if (msg.config) {
|
|
186
|
+
this.config = { ...this.config, ...msg.config }
|
|
187
|
+
}
|
|
188
|
+
if (msg.clear) {
|
|
189
|
+
this.clearMessages()
|
|
190
|
+
}
|
|
191
|
+
})
|
|
143
192
|
},
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const base64Data = e.target.result.split(',')[1]; // Remove data URL prefix
|
|
151
|
-
|
|
152
|
-
resolve({
|
|
153
|
-
name: file.name,
|
|
154
|
-
type: file.type,
|
|
155
|
-
size: file.size,
|
|
156
|
-
base64Data: base64Data,
|
|
157
|
-
});
|
|
158
|
-
} catch (error) {
|
|
159
|
-
reject(error);
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
reader.onerror = () => reject(new Error('Failed to read audio'));
|
|
163
|
-
reader.readAsDataURL(file);
|
|
164
|
-
});
|
|
193
|
+
|
|
194
|
+
removeSocketListeners() {
|
|
195
|
+
this.$socket.off('deepchat-newMessage:' + this.id)
|
|
196
|
+
this.$socket.off('deepchat-updateConfig:' + this.id)
|
|
197
|
+
this.$socket.off('deepchat-clearMessages:' + this.id)
|
|
198
|
+
this.$socket.off('msg-input:' + this.id)
|
|
165
199
|
},
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
resolve({
|
|
175
|
-
name: file.name,
|
|
176
|
-
type: file.type,
|
|
177
|
-
size: file.size,
|
|
178
|
-
fileData: base64Data, // Use fileData for documents
|
|
179
|
-
});
|
|
180
|
-
} catch (error) {
|
|
181
|
-
reject(error);
|
|
200
|
+
|
|
201
|
+
applyConfiguration() {
|
|
202
|
+
// Konfiguration aus props übernehmen
|
|
203
|
+
if (this.props) {
|
|
204
|
+
Object.keys(this.props).forEach(key => {
|
|
205
|
+
if (this.config.hasOwnProperty(key)) {
|
|
206
|
+
this.config[key] = this.props[key]
|
|
182
207
|
}
|
|
183
|
-
}
|
|
184
|
-
reader.onerror = () => reject(new Error('Failed to read document'));
|
|
185
|
-
reader.readAsDataURL(file);
|
|
186
|
-
});
|
|
187
|
-
},
|
|
188
|
-
|
|
189
|
-
formatForChatGPT(conversation, textOnly = false) {
|
|
190
|
-
const payload = {
|
|
191
|
-
messages: conversation.map((msg) => this.formatMessage(msg, textOnly)),
|
|
192
|
-
model: this.props.model,
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
// Add ChatGPT API extensions
|
|
196
|
-
if (this.props.tools) {
|
|
197
|
-
payload.tools = this.props.tools;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (this.props.tool_choice) {
|
|
201
|
-
payload.tool_choice = this.props.tool_choice;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
if (this.props.temperature !== undefined) {
|
|
205
|
-
payload.temperature = this.props.temperature;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
if (this.props.max_tokens) {
|
|
209
|
-
payload.max_tokens = this.props.max_tokens;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
if (this.props.top_p !== undefined) {
|
|
213
|
-
payload.top_p = this.props.top_p;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
if (this.props.frequency_penalty !== undefined) {
|
|
217
|
-
payload.frequency_penalty = this.props.frequency_penalty;
|
|
208
|
+
})
|
|
218
209
|
}
|
|
219
|
-
|
|
220
|
-
if (this.props.presence_penalty !== undefined) {
|
|
221
|
-
payload.presence_penalty = this.props.presence_penalty;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
if (this.props.response_format) {
|
|
225
|
-
payload.response_format = this.props.response_format;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
return payload;
|
|
229
210
|
},
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
return message;
|
|
211
|
+
|
|
212
|
+
addMessage(content, role = 'ai', isHtml = false, files = []) {
|
|
213
|
+
try {
|
|
214
|
+
if (this.$refs.deepChat) {
|
|
215
|
+
const message = {
|
|
216
|
+
text: content,
|
|
217
|
+
role: role
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (isHtml) {
|
|
221
|
+
message.html = content
|
|
222
|
+
delete message.text
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (files && files.length > 0) {
|
|
226
|
+
message.files = files
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Nachricht zu Deep Chat hinzufügen
|
|
230
|
+
this.$refs.deepChat.addMessage(message)
|
|
231
|
+
this.messages.push(message)
|
|
232
|
+
}
|
|
233
|
+
} catch (error) {
|
|
234
|
+
console.error('Error adding message to Deep Chat:', error)
|
|
255
235
|
}
|
|
256
|
-
|
|
257
|
-
// Handle text-only messages
|
|
258
|
-
message.content = msg.text || msg.content || '';
|
|
259
|
-
return message;
|
|
260
236
|
},
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
content.push({
|
|
268
|
-
type: 'image_url',
|
|
269
|
-
image_url: { url: file.src },
|
|
270
|
-
});
|
|
271
|
-
} else if (!textOnly && file.type && file.type.startsWith('audio/') && file.base64Data) {
|
|
272
|
-
const format = this.getAudioFormat(file.type);
|
|
273
|
-
content.push({
|
|
274
|
-
type: 'input_audio',
|
|
275
|
-
input_audio: {
|
|
276
|
-
data: file.base64Data,
|
|
277
|
-
format: format,
|
|
278
|
-
},
|
|
279
|
-
});
|
|
280
|
-
} else if (!textOnly && file.fileData) {
|
|
281
|
-
content.push({
|
|
282
|
-
type: 'file',
|
|
283
|
-
file: {
|
|
284
|
-
filename: file.name,
|
|
285
|
-
file_data: file.fileData,
|
|
286
|
-
},
|
|
287
|
-
});
|
|
237
|
+
|
|
238
|
+
clearMessages() {
|
|
239
|
+
try {
|
|
240
|
+
if (this.$refs.deepChat) {
|
|
241
|
+
this.$refs.deepChat.clearMessages()
|
|
242
|
+
this.messages = []
|
|
288
243
|
}
|
|
289
|
-
})
|
|
290
|
-
|
|
291
|
-
|
|
244
|
+
} catch (error) {
|
|
245
|
+
console.error('Error clearing Deep Chat messages:', error)
|
|
246
|
+
}
|
|
292
247
|
},
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
248
|
+
|
|
249
|
+
handleCustomConnection(body, signals) {
|
|
250
|
+
// Node-RED Integration: Nachricht an Node-RED senden
|
|
251
|
+
this.$socket.emit('chat-message', this.id, {
|
|
252
|
+
message: body.messages || body,
|
|
253
|
+
timestamp: new Date().toISOString(),
|
|
254
|
+
files: body.files || []
|
|
255
|
+
})
|
|
256
|
+
|
|
257
|
+
// Temporary loading message
|
|
258
|
+
signals.onOpen({
|
|
259
|
+
text: 'Processing...',
|
|
260
|
+
role: 'ai'
|
|
261
|
+
})
|
|
300
262
|
},
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
263
|
+
|
|
264
|
+
handleNewMessage(event) {
|
|
265
|
+
// Event an Node-RED weiterleiten
|
|
266
|
+
this.$socket.emit('deepchat-onNewMessage', this.id, {
|
|
267
|
+
message: event.message,
|
|
268
|
+
role: event.role || 'user',
|
|
269
|
+
timestamp: new Date().toISOString()
|
|
270
|
+
})
|
|
308
271
|
},
|
|
272
|
+
|
|
273
|
+
handleClearMessages() {
|
|
274
|
+
// Event an Node-RED weiterleiten
|
|
275
|
+
this.$socket.emit('deepchat-onClearMessages', this.id, {
|
|
276
|
+
timestamp: new Date().toISOString()
|
|
277
|
+
})
|
|
278
|
+
},
|
|
279
|
+
|
|
280
|
+
handleComponentRender(event) {
|
|
281
|
+
// Event an Node-RED weiterleiten
|
|
282
|
+
this.$socket.emit('deepchat-onComponentRender', this.id, {
|
|
283
|
+
event: event,
|
|
284
|
+
timestamp: new Date().toISOString()
|
|
285
|
+
})
|
|
286
|
+
},
|
|
287
|
+
|
|
288
|
+
handleResponse(event) {
|
|
289
|
+
console.log('Deep Chat Response:', event)
|
|
290
|
+
},
|
|
291
|
+
|
|
292
|
+
handleError(error) {
|
|
293
|
+
console.error('Deep Chat Error:', error)
|
|
294
|
+
|
|
295
|
+
// Fehler an Node-RED melden
|
|
296
|
+
this.$socket.emit('chat-message', this.id, {
|
|
297
|
+
error: error.message || error,
|
|
298
|
+
timestamp: new Date().toISOString()
|
|
299
|
+
})
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
</script>
|
|
309
304
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
role: 'ai',
|
|
318
|
-
content: fullResponse.message?.content || fullResponse.content,
|
|
319
|
-
text: fullResponse.message?.content || fullResponse.content,
|
|
320
|
-
fullResponse: fullResponse,
|
|
321
|
-
};
|
|
305
|
+
<style scoped>
|
|
306
|
+
.ui-deepchat-container {
|
|
307
|
+
position: relative;
|
|
308
|
+
border-radius: 8px;
|
|
309
|
+
overflow: hidden;
|
|
310
|
+
background: var(--v-theme-surface);
|
|
311
|
+
}
|
|
322
312
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
313
|
+
/* Deep Chat Styling Integration */
|
|
314
|
+
.ui-deepchat-container :deep(deep-chat) {
|
|
315
|
+
width: 100% !important;
|
|
316
|
+
height: 100% !important;
|
|
317
|
+
border: none !important;
|
|
318
|
+
border-radius: 8px;
|
|
319
|
+
font-family: var(--v-font-family) !important;
|
|
320
|
+
}
|
|
328
321
|
|
|
329
|
-
|
|
322
|
+
/* Dark theme support */
|
|
323
|
+
.ui-deepchat-container :deep(deep-chat) {
|
|
324
|
+
--chat-background-color: var(--v-theme-surface);
|
|
325
|
+
--user-message-color: var(--v-theme-primary);
|
|
326
|
+
--ai-message-color: var(--v-theme-secondary);
|
|
327
|
+
--border-color: var(--v-theme-outline);
|
|
328
|
+
--text-color: var(--v-theme-on-surface);
|
|
329
|
+
--placeholder-color: var(--v-theme-on-surface-variant);
|
|
330
|
+
}
|
|
330
331
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
role: 'ai',
|
|
337
|
-
});
|
|
338
|
-
} else if (fullResponse.message?.content || fullResponse.content) {
|
|
339
|
-
// Normal text response
|
|
340
|
-
signals.onResponse({
|
|
341
|
-
text: fullResponse.message?.content || fullResponse.content,
|
|
342
|
-
role: 'ai',
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
} catch (error) {
|
|
346
|
-
console.error('Error handling response:', error);
|
|
347
|
-
this.sendErrorResponse(signals, 'Error processing response');
|
|
348
|
-
}
|
|
349
|
-
},
|
|
332
|
+
/* Input area styling */
|
|
333
|
+
.ui-deepchat-container :deep(.text-input-container) {
|
|
334
|
+
border-top: 1px solid var(--v-theme-outline) !important;
|
|
335
|
+
background: var(--v-theme-surface) !important;
|
|
336
|
+
}
|
|
350
337
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
role: 'ai',
|
|
356
|
-
});
|
|
357
|
-
}
|
|
358
|
-
},
|
|
359
|
-
},
|
|
360
|
-
};
|
|
361
|
-
</script>
|
|
338
|
+
/* Message bubbles */
|
|
339
|
+
.ui-deepchat-container :deep(.message-bubble) {
|
|
340
|
+
border-radius: 12px !important;
|
|
341
|
+
}
|
|
362
342
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
343
|
+
/* Responsive design */
|
|
344
|
+
@media (max-width: 768px) {
|
|
345
|
+
.ui-deepchat-container {
|
|
346
|
+
border-radius: 0;
|
|
347
|
+
}
|
|
368
348
|
}
|
|
369
|
-
</style>
|
|
349
|
+
</style>
|